4👍
✅
Oki, here goes:
1) pip-install ‘django-solo’.
2) Make a new app with manage.py startapp config
.
2a) File config/models.py
:
from django.db import models
from solo.models import SingletonModel
class SiteConfiguration(SingletonModel):
site_name = models.CharField(max_length=255, default='Site Name')
maintenance_mode = models.BooleanField(default=False)
def __str__(self):
return u"Site Configuration"
class Meta:
verbose_name = "Site Configuration"
2b) File config/views.py
:
from rest_framework.views import APIView
from rest_framework.response import Response
from .models import SiteConfiguration
config = SiteConfiguration.get_solo()
class SiteConfiguration(APIView):
permission_classes = []
def get(self, request, format=None):
"""
Return site configuration key-values.
"""
return Response({
'name': config.site_name
})
3) The next problem is adding the view to the router. Using the DefaultRouter
, one cannot register APIview
s, so this guy had a simple HybridRouter
solution [https://stackoverflow.com/a/23321478/1008905].
3a) Make a custom_routers.py
in your project folder (where your main urls.py
-file is located), with this content:
from rest_framework import routers, views, reverse, response
class HybridRouter(routers.DefaultRouter):
def __init__(self, *args, **kwargs):
super(HybridRouter, self).__init__(*args, **kwargs)
self._api_view_urls = {}
def add_api_view(self, name, url):
self._api_view_urls[name] = url
def remove_api_view(self, name):
del self._api_view_urls[name]
@property
def api_view_urls(self):
ret = {}
ret.update(self._api_view_urls)
return ret
def get_urls(self):
urls = super(HybridRouter, self).get_urls()
for api_view_key in self._api_view_urls.keys():
urls.append(self._api_view_urls[api_view_key])
return urls
def get_api_root_view(self):
# Copy the following block from Default Router
api_root_dict = {}
list_name = self.routes[0].name
for prefix, viewset, basename in self.registry:
api_root_dict[prefix] = list_name.format(basename=basename)
api_view_urls = self._api_view_urls
class APIRoot(views.APIView):
_ignore_model_permissions = True
def get(self, request, format=None):
ret = {}
for key, url_name in api_root_dict.items():
ret[key] = reverse.reverse(url_name, request=request, format=format)
# In addition to what had been added, now add the APIView urls
for api_view_key in api_view_urls.keys():
ret[api_view_key] = reverse.reverse(api_view_urls[api_view_key].name, request=request, format=format)
return response.Response(ret)
return APIRoot.as_view()
3b) In your main urls.py
do this:
from .custom_routers import HybridRouter
# The rest is from the `rest-framework` polls-tutorial.
rest_router = HybridRouter()
rest_router.register(r'users', UserViewSet)
rest_router.register(r'polls', PollViewSet)
rest_router.add_api_view("config", url(r'^config/$', configViews.SiteConfiguration.as_view(), name='site_configuration'))
# Wire up our API using automatic URL routing.
# Additionally, we include login URLs for the browsable API.
urlpatterns = [
url(r'^', include(rest_router.urls), name='rest_api'),
url(r'^auth/', include('rest_framework.urls', namespace='rest_framework')),
url(r'^admin/', include(admin.site.urls), name='admin'),
]
All which seems to work for me.
3👍
An alternate approach that doesn’t require outside dependencies:
# models.py
from django.db import models
class MySingleton(models.Model):
def save(self, *args, **kwargs):
self.pk = 1
return super().save(*args, **kwargs)
@classmethod
def singleton(cls):
obj, _ = cls.objects.get_or_create(pk=1)
return obj
# serializers.py
from rest_framework import serializers
from . import models
class MySingletonSerializer(serializers.ModelSerializer):
class Meta:
model = models.MySingleton
fields = "__all__"
# views.py
from rest_framework import generics
from . import models
from . import serializers
class SingletonView(generics.RetrieveAPIView):
serializer_class = serializers.MySingletonSerializer
def get_object(self):
return models.MySingleton.singleton()
- [Django]-Using mongoengine with models.ImageField
- [Django]-Using a static website generator for a blog on a dynamic website?
- [Django]-Django: ForeignKey on_delete SET_DEFAULT behavior
- [Django]-Django send_mail returns SMTPConnectError
Source:stackexchange.com