Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

DefaultRouter class not creating API root view for all apps in python

I'm creating a simple Python API with two apps in it named as snippets and polls. For single entry point to my API, I'm using DefaultRouter class instead of a regular function-based view and the @api_view decorator.

As stated in Django Rest Framework Tutorial that

The DefaultRouter class automatically creates the API root view

I'm having issue in API root view. Here is my snippets/urls.py

router = DefaultRouter()
router.register(r'snippets', views.SnippetViewSet)
router.register(r'users', views.UserViewSet)

urlpatterns = [
    url(r'^', include(router.urls)),
    url(r'^api-auth/', include('rest_framework.urls', namespace='rest_framework'))
]

this is my polls/urls.py

router = DefaultRouter()
router.register(r'actors', views.ActorViewSet)

urlpatterns = [
    url(r'^', include(router.urls)),
    url(r'^api-auth/', include('rest_framework.urls', namespace='rest_framework'))
]

My /urls.py is as following

urlpatterns = [
 url(r'^admin/', admin.site.urls),          
 url(r'^', include('snippets.urls')),
 url(r'^', include('polls.urls')),
 url(r'^api-auth/', include('rest_framework.urls',
                           namespace='rest_framework')),
]

Now when I start server and load app in browser, it only shows snippets' url as entry point like this (polls' url is missing)

enter image description here

and if change my root urls.py like this (first add polls.urls and then snippets.urls)

urlpatterns = [
 url(r'^admin/', admin.site.urls),          
 url(r'^', include('polls.urls')),
 url(r'^', include('snippets.urls')),
 url(r'^api-auth/', include('rest_framework.urls',
                       namespace='rest_framework')),
]

Now it shows polls' urls (missing snippets urls)

enter image description here

But I want both apps' urls over there. I don't know what I'm missing here. Any kind of help will be appreciated.

like image 700
Naila Akbar Avatar asked May 06 '16 06:05

Naila Akbar


2 Answers

Your url.py can look like this (To create a custom documentation page)

from django.urls import path, include
from rest_framework import routers
from rest_framework.response import Response
from rest_framework.views import APIView
from . import views


class DocsView(APIView):
    """
    RESTFul Documentation of my app
    """
    def get(self, request, *args, **kwargs):
        apidocs = {'api1title': request.build_absolute_uri('api1endpoint/'),
                   'api2title': request.build_absolute_uri('api2endpoint/'),
                   'api3title': request.build_absolute_uri('api3endpoint/'),
                   'api4title': request.build_absolute_uri('api4endpoint/'),
                   }
        return Response(apidocs)


router = routers.DefaultRouter()
router.register('api1endpoint', views.API1ViewSet)
router.register('api2endpoint', views.API2ViewSet)


urlpatterns = [
    path('', DocsView.as_view()),
    path('', include(router.urls)),
    path('api3endpoint/', views.API4View.as_view()),
    path('api4endpoint/', views.API4View.as_view()),
    ]
like image 193
shbli Avatar answered Nov 18 '22 04:11

shbli


You shouldn't have same regex patterns that map to different views in the urlpatterns. When this happens, the server will just use the first matched pattern and routes to the first matched view.

Other alternative maybe you can create the default router and registers the two views in the root folder instead so that it can handle the api_rootview for both viewsets.

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

like image 5
dekauliya Avatar answered Nov 18 '22 06:11

dekauliya