Маршрутизация Django Rest Framework с префиксом первичного ключа
Я использую DRF DefaultRouter
следующим образом.
# 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
Но когда я посещаю URL /book/1/reservation/
, он говорит, что шаблон url не найден.
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.
Я использую bk
для захвата идентификатора книги.
Это потому, что он реализует <int:bk>
как regex, поэтому без какой-либо интерпретации. Вероятно, проще всего это сделать с помощью двух маршрутизаторов:
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)),
]
В ReservationViewSet
вы можете, например, фильтровать с помощью bk
:
class ReservationViewSet(viewsets.ModelViewSet):
serializer_class = ReservationSerializer
def get_queryset(self):
return Reservation.objects.filter(book_id=self.kwargs['bk'])
Просто хотел добавить это к принятому ответу ... Вы также можете сделать это с помощью того же маршрутизатора, просто вставьте pk в URL в форме regex, как предлагает сообщение об ошибке:
# urls.py
router = DefaultRouter()
router.register('book', BookingViewSet, basename='booking')
router.register('book/(?P<bk>[^/.]+)/reservation', ReservationViewSet, basename='reservation')
urlpatterns = [
path('', include(router.urls)),
]
Затем вы можете получить доступ к аргументу bk
в вашем представлении, используя self.kwargs['bk']
.