navyad
navyad

Reputation: 3860

Django-Rest-Framework: router not working

I have this base urls file:

url(r'^locations/', include('locations.urls')),

in locations.urls.py app i have following url references:

url(r'^/?$', LocationList.as_view()),
url(r'^(?P<pk>[a-zA-Z0-9\-\$]+)/?$', LocationDetail.as_view()),
url(r'services/?$', LocationServiceseList.as_view()),
url(r'services/(?P<service_id>[a-zA-Z0-9\-\$]+)/?$', LocationServicesDetail.as_view()),

For above url referce i want to user routers of Django-Rest-framework

for locations/services/ i created GenericViewSet from DRF and i tried router successfully made following changes in locations.urls:

router = routers.SimpleRouter()
router.register(r'services', LocationServiceSet)

url(r'^/?$', LocationList.as_view()),
url(r'^(?P<vehicle_id>[a-zA-Z0-9\-\$]+)/?$', LocationDetail.as_view()),
url(r'^', include(router.urls)),

Now i want to create router for /locations/ endpoinsts and made following changes

router = routers.SimpleRouter()
router.register(r'services', LocationServiceSet)
router.register(r'', LocationSet)


url(r'^', include(router.urls)),

Getting 404 for /locations/ with stacktrace shows although /locations/services/ work fine:

^locations/ ^ ^services/$ [name='locationsservice-list']
^locations/ ^ ^services/(?P<pk>[^/.]+)/$ [name='locationsservice-detail']
^locations/ ^ ^/$ [name='locations-list']
^locations/ ^ ^/(?P<pk>[^/.]+)/$ [name='locations-detail']

Upvotes: 1

Views: 2429

Answers (1)

Rahul Gupta
Rahul Gupta

Reputation: 47846

This is happening because of an empty string prefix argument to router.register() function for LocationSet.

When you used an empty string '' as prefix for registering the router, it generated the following urls. (Notice the double slash in urls)

locations//$ # double slash in urls
locations//(?P<pk>[^/.]+)/$ # double slash in urls 

To solve this, you need to define and register this router in base urls file instead of locations/urls.py with prefix value as locations.

# base urls.py
router = routers.SimpleRouter() 
router.register(r'locations', LocationSet)

...
url(r'^locations/', include('locations.urls')), # include app urls
url(r'^', include(router.urls)), # include router urls

Another solution is to use a non-empty string as prefix while registering the router for LocationSet in locations/urls.py.

Upvotes: 2

Related Questions