By continuing to navigate on this website, you accept the use of cookies to serve you more relevant services & content.
For more information and to change the setting of cookies on your computer, please read our Cookie Policy.

Understanding Routers in Django-Rest-Framework

We can use function-based views(FBV) and generic views(class-based views[CBV]) to develop rest API by using the Django-REST-Framework. It's a good approach to use FBV or CBV  with defined URL configurations. Mapping views with the URL's is a good idea but, probably not the best. We can better organize this by using Routers and ViewSets.

Advantages using ViewSets and Routers over traditional views

  • We can avoid configuring the URL's with views.
  • Routers generate automatic URL patterns and maps every URL to its respective method based on a type of the request.
  • It deals with a little abstraction but, it can speed up the development process.
  • We can also speed up the debugging process as well with a little practice.
  • Router generates standardized url patterns.
  • We can expect consistent behaviour from viewsets and routers
  • We can avoid repetitive code in views. For example, in traditional views we need to have two api views for detail and list. But, we can achive it with a single ViewSet class.
  • If we develop a large api and if we don't use viewset and routers then it will result in more views and urls. It will definitely affect our application(api) maintainablity and development time.

Lets see how routers generate dynamic urls

# serializers.py
from rest_framework import serializers

class UserSerializer(serializers.HyperlinkedModelSerializer):
    class Meta:
        model = User
        fields = ('url', 'username', 'email', 'is_staff')
# viewsets.py
from rest_framework import viewsets
from .serializers import UserSerializer

class UserViewSet(viewsets.ModelViewSet):
    queryset = User.objects.all()
    serializer_class = UserSerializer

# urls.py
from django.conf.urls import url, include
from .viewsets import UserViewSet

router = routers.DefaultRouter()
router.register(r'custom_name', UserViewSet)


urlpatterns = [
    # .......
    url(r'^', include(router.urls, namespace="myapp")),
    # .......
]

# Now, try the following in the django shell (python manage.py shell)
from test_rest.urls import router

for url in router.urls:
    print(i.__dict__)

# You will get output like below
{'_regex_dict': {}, u'regex': <_sre.SRE_Pattern object at 0x7ff790dbd730>, 'name': u'user-list', 'callback': <function CUserViewSet at 0x7ff790dd1b18>, '_regex': u'^custom_name/$', 'default_args': {}}
{'_regex_dict': {}, 'callback': <function CUserViewSet at 0x7ff790dd1b18>, 'name': u'user-list', '_regex': u'^custom_name\\.(?P<format>[a-z0-9]+)/?$', 'default_args': {}}
{'_regex_dict': {}, u'regex': <_sre.SRE_Pattern object at 0x7ff790dbc280>, 'name': u'user-detail', 'callback': <function CUserViewSet at 0x7ff790dd1c08>, '_regex': u'^custom_name/(?P<pk>[^/.]+)/$', 'default_args': {}}
{'_regex_dict': {}, 'callback': <function CUserViewSet at 0x7ff790dd1c08>, 'name': u'user-detail', '_regex': u'^custom_name/(?P<pk>[^/.]+)\\.(?P<format>[a-z0-9]+)/?$', 'default_args': {}}
{'_regex_dict': {}, u'regex': <_sre.SRE_Pattern object at 0x7ff790e61ab0>, 'name': u'api-root', 'callback': <function APIRootView at 0x7ff790dd1cf8>, '_regex': u'^$', 'default_args': {}}
{'_regex_dict': {}, 'callback': <function APIRootView at 0x7ff790dd1cf8>, 'name': u'api-root', '_regex': u'^\\.(?P<format>[a-z0-9]+)/?$', 'default_args': {}}

After writing the viewsets we have register the viewsets with "DefaultRouter".  You can look into urls.py in above code to know how to register a viewset. We have discussed that router generates urls automatically. In above code we have used djnago shell to know how routers are generating the urls automatically. From above code, we can find that every url has keys "_regex", "name", "callback".

_regex: It conains the reggular expression of url. we gave "custom_name" prefix while registering the ViewSet. By using prefix router formed regular expressions u'^custom_name/$',  u'^custom_name/(?P<pk>[^/.]+)/$'. The pattern which contains "pk" as keyword argument will matches methods  "detail", "update", "partial_update", "delete" based on type of the request. The pattern which doesn't have "pk" matches the method "list". 

name: It is used to renerate the url by using "reverse"It will form names "{basename}-list", "{basename}-detail" based on model name. In above code, I have used a model with name "User". That's the reason router generated the names "user-list", "user-detail". By default basename generally taken as lowercase of model name. Otherwise we have to  pass it as a third parameter like "router.register(prefix=r'custom_name', viewset=UserViewSet, base_name="custom_name")"

callback: It is a method of the ViewSet. It is mapped to the url based on type of the request. 

 URL pattern Request type Mapping Method URL name
'^{prefix}/list/$' GET list {basename}-list
POST create
'^{prefix}/{lookup}/$' GET retrieve {basename}-detail
PUT update
PATCH partial_update
DELETE destroy

As we discussed earlier ViewSets reduces writing of more views. That's the reason router generated the more urls for ViewSet. It will generate the urls based on the methods that the ViewSet contains.

References:

http://www.django-rest-framework.org/api-guide/routers/

https://github.com/encode/django-rest-framework/blob/master/rest_framework/routers.py

    Posted On
  • 03 October 2017
  • By
  • Micropyramid

Need any Help in your Project?Let's Talk

Latest Comments
Related Articles
Working with Django Plugins

This blog describes about how to work with django-plugins. Django Plugin is a Simple Plugin Framework for Django. By using django-plugins, you can make your ...

Continue Reading...
How to create thumbnail image in Django templates using sorl-thumbnail?

Sorl thumbnail is the package which is being widely used to generate thumbnail in Django. It will create thumbnail of given size for the given ...

Continue Reading...
Django Forms basics explained

Django forms is powerful module to help django application development in rendering html from model, validate input from http request to model specifications. And we ...

Continue Reading...
open source packages

Subscribe To our news letter

Subscribe and Stay Updated about our Webinars, news and articles on Django, Python, Machine Learning, Amazon Web Services, DevOps, Salesforce, ReactJS, AngularJS, React Native.
* We don't provide your email contact details to any third parties