Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Django REST Framework: How to add prefix in URL for versioning

I am trying to create version for REST application. Here is my URL Examle

www.myapi.com/foo [default version]
www.myapi.com/v1/foo [version one]

This is the project structure

├── __init__.py
├── settings.py
├── urls.py
├── default_app
│ ├── __init__.py
│ ├── serializer.py
│ ├── models.py
│ ├── views.py
│ ├── urls.py
│ 
└── v1_app
├── __init__.py
├── serializer.py
├── models.py
├── views.py
├── urls.py

default_app urls.py

from django.conf.urls import *
from default_app import views as df_views
from rest_framework import routers

router = routers.DefaultRouter()
router.register(r'foo', df_views.viewname, "foo")
urlpatterns = router.urls

v1_app urls.py

from django.conf.urls import *
from v1_app import views as ver_views
from rest_framework import routers

router = routers.DefaultRouter()
router.register(r'foo', ver_views.viewname, "foo")
urlpatterns = router.urls

main file for urls.py

from django.conf.urls import patterns, include, url
from defualt_app import urls as default_urls
from v1_app import urls as v1_urls
from django.contrib.staticfiles.urls import staticfiles_urlpatterns



urlpatterns += patterns('',
    url(r'^', include(default_urls, namespace="default")),
    url(r'^v1/', include(v1_urls, namespace="v1"))
)

urlpatterns += staticfiles_urlpatterns()

My issue is, when i using simple url without any prefix then it is working

www.myapi.com/foo

and when i used version prefix v1 or v2 then it throws error [Page not found (404)]

www.myapi.com/v1/foo

I got this idea from this link https://stackoverflow.com/a/21839842/1558544

If I don't use middleware class then is this possible to get same result?

Thank you

like image 436
Shoaib Ijaz Avatar asked Nov 05 '14 12:11

Shoaib Ijaz


People also ask

What is Basename in Django URLs?

basename - The base to use for the URL names that are created. If unset the basename will be automatically generated based on the queryset attribute of the viewset, if it has one. Note that if the viewset does not include a queryset attribute then you must set basename when registering the viewset.

Which setting value should be used for request version when no versioning information is present?

Other versioning settingsDEFAULT_VERSION . The value that should be used for request. version when no versioning information is present.

What is Format_suffix_patterns?

format_suffix_patterns. Signature: format_suffix_patterns(urlpatterns, suffix_required=False, allowed=None) Returns a URL pattern list which includes format suffix patterns appended to each of the URL patterns provided.


1 Answers

Django REST Framework does not support url namespaces well, but there are solutions to making them work for most cases.

In the case of serializers, you must define all fields that are hyperlinked with a HyperlinkedRelatedField, including the url field that is automatically added, which is a HyperlinkedIdentityField. This includes setting the view_name argument on all of the fields to the correct, automatically generated view name. This should be something like [namespace]:[base_name]-detail.

But this also means you cannot use the DefaultRouter index page that is generated by the DefaultRouter, as it does not handle namespaces at all. In order to get one, you are going to need to either create your own, or override the automatically generated view in the router.

like image 64
Kevin Brown-Silva Avatar answered Oct 16 '22 18:10

Kevin Brown-Silva