Django-Rest-Framework router register

16,902

Try explicitly adding a base_name to each registered viewset:

router = routers.DefaultRouter()
router.register(r'vocabs', views.VocabViewSet, 'vocabs')
router.register(r'terms', views.TermViewSet, 'terms')
router.register(r'disciplines', views.DisciplineViewSet, 'disciplines')

As a side note, your should probably exclude get_ prefix in your urls since that is not RESTful. Each URL should specify a resource, not an action on the resource. Thats what HTTP verbs are used for:

GET http://127.0.0.1:8000/service/vocabs/

# or this to create resource
POST http://127.0.0.1:8000/service/vocabs/

...
Share:
16,902
ePascoal
Author by

ePascoal

I'm just a curious guy.

Updated on June 26, 2022

Comments

  • ePascoal
    ePascoal almost 2 years

    i'm having a issue when i try to register more than 2 routers using Django-REST-FRAMEWORK. Please take a look on my example:

    urls.py

    from rest_framework import routers
    from collaborativeAPP import views
    
    router = routers.DefaultRouter()
    router.register(r'get_vocab', views.VocabViewSet)
    router.register(r'get_term', views.TermViewSet)
    router.register(r'get_discipline', views.DisciplineViewSet)
    
    urlpatterns = patterns(
    ...
        url(r'^service/', include(router.urls))
    )
    

    views.py

    class VocabViewSet(viewsets.ModelViewSet):
        queryset = Vocab.objects.all()
        serializer_class = VocabSerializer
    
    class TermViewSet(viewsets.ModelViewSet):
        queryset = Term.objects.all()
        serializer_class = TermSerializer
    
    class DisciplineViewSet(viewsets.ModelViewSet):
        queryset = Vocab.objects.filter(kwdGroup=4)
        serializer_class = DisciplineSerializer
    

    the result in my localhost is the following:

    http://localhost:8000/service/

    HTTP 200 OK
    Content-Type: application/json
    Vary: Accept
    Allow: GET, HEAD, OPTIONS
    
    {
        "get_vocab": "http://127.0.0.1:8000/service/get_discipline/",
        "get_term": "http://127.0.0.1:8000/service/get_term/",
        "get_discipline": "http://127.0.0.1:8000/service/get_discipline/"
    }
    

    As you can see i have registered 3 routers expecting that they will display 3 urls for each methodname(get_vocab, get_term, get_discipline). The final result is get_discipline is occuring two times and get_vocab url is missing.

    Notice that for methods that uses different models it works fine, but in case of get_discipline and get_vocab they use the same model which will create this mess. Should i use a viewset for each model? If so, how can a define different methods in a viewset?

    It should occur the following result:

     HTTP 200 OK
     Content-Type: application/json
     Vary: Accept
     Allow: GET, HEAD, OPTIONS
    
     {
         "get_vocab": "http://127.0.0.1:8000/service/get_vocab/",
         "get_term": "http://127.0.0.1:8000/service/get_term/",
         "get_discipline": "http://127.0.0.1:8000/service/get_discipline/"
     }
    

    What am i missing? I supposed that i could register as many routers as i want. It is supposed to have one router per model? Why doesn't seem to work for viewsets that share a same model?

  • ePascoal
    ePascoal almost 9 years
    Thanks for the tip.You are right. In fact the http request already provide that information.
  • mirek
    mirek almost 2 years
    Doesn't help for me.