Home > Net >  Django Rest Framework routing with primary key prefix
Django Rest Framework routing with primary key prefix

Time:02-02

I'm using DRF DefaultRouter as follows.

# urls.py
router = DefaultRouter()
router.register('book', BookingViewSet, basename='booking')
router.register('book/<int:bk>/reservation', ReservationViewSet, basename='reservation')

urlpatterns = [
   path('', include(router.urls)),
]

# view
class ReservationViewSet(viewsets.ModelViewSet):
    serializer_class = ReservationSerializer
    queryset = Reservation.objects.all() # for testing only

But when I visit the URL /book/1/reservation/ it says no url pattern found.

lending/ ^book/<int:bk>/reservation/$ [name='reservation-list']
lending/ ^book/<int:bk>/reservation\.(?P<format>[a-z0-9] )/?$ [name='reservation-list']
lending/ ^book/<int:bk>/reservation/(?P<pk>[^/.] )/$ [name='reservation-detail']
lending/ ^book/<int:bk>/reservation/(?P<pk>[^/.] )\.(?P<format>[a-z0-9] )/?$ [name='reservation-detail'] 

The current path, lending/book/1/reservation/, didn’t match any of these. 

I'm using bk to capture book id.

CodePudding user response:

That's because it implements the <int:bk> as regex, so without any interpretation. Probably the simplest way to do this is with two routers:

router1 = DefaultRouter()
router1.register('book', BookingViewSet, basename='booking')

router2 = DefaultRouter()
router2.register('reservation', ReservationViewSet, basename='reservation')

urlpatterns = [
   path('', include(router1.urls)),
   path('book/<int:bk>/', include(router2.urls)),
]

In the ReservationViewSet you can then for example filter with bk:

class ReservationViewSet(viewsets.ModelViewSet):
    serializer_class = ReservationSerializer

    def get_queryset(self):
        return Reservation.objects.filter(book_id=self.kwargs['bk'])
  •  Tags:  
  • Related