Как вложить маршруты URL в Django Rest Framework (DRF) RetrieveUpdateDestroyAPIView без маршрутизатора
Я использую Django rest framework и RetrieveUpdateDestroyAPIView и пытаюсь реализовать вложенные шаблоны URL.
# my current URLs structure is like
/api/v1/kitchens/ - ListCreateAPIView
/api/v1/kitchens/1/ - RetrieveUpdateDestroyAPIView
/api/v1/orders/ - ListCreateAPIView
/api/v1/orders/1/ - RetrieveUpdateDestroyAPIView
/api/v1/items/ - ListCreateAPIView
/api/v1/items/1/ - RetrieveUpdateDestroyAPIView
Вышеприведенная структура прекрасно работает со всеми операциями, но чтобы получить список элементов или заказов под одной кухней, я пытаюсь достичь чего-то живого, описанного ниже.
в файле views.py есть что-то вроде следующего.
class KitchenListView(generics.ListCreateAPIView):
queryset = Kitchen.objects.all()
serializer_class = KitchenSerializer
pagination_class = LimitOffsetPagination
permission_classes = (permissions.IsAuthenticatedOrReadOnly,)
authentication_classes = (TokenAuthentication,)
filter_backends = (DjangoFilterBackend,)
filter_fields = ("user",)
class KitchenDetailView(generics.RetrieveUpdateDestroyAPIView):
queryset = Kitchen.objects.all()
serializer_class = KitchenDetailsSerializer
permission_classes = (
permissions.IsAuthenticatedOrReadOnly,
IsOwnerOrReadOnly,
)
authentication_classes = (TokenAuthentication,)
# I want to create this structure.
/api/v1/kitchens/ - List
/api/v1/kitchens/1/ - Details
/api/v1/kitchens/1/orders/ - Orders List
/api/v1/kitchens/1/orders/1/ - Order Details
/api/v1/kitchens/1/items/ - Items List
/api/v1/kitchens/1/items/1/ - Item Details
Я пытаюсь достичь чего-то подобного. Пожалуйста, предложите мне лучшее решение, если у кого-нибудь есть, и что лучше использовать - общие представления API или наборы представлений, поскольку мой проект является крупномасштабным проектом.
Заранее спасибо.
Прежде всего, я предполагаю, что у вас есть представление Order и представление Item; в обоих ваших представлениях попробуйте следующее:
from rest_framework.generics import get_object_or_404
class OrderListView(generics.ListCreateAPIView):
...
def get_queryset(self):
if self.kwargs.get('kitchen_pk'):
return self.queryset.filter(kitchen_id=self.kwargs.get('kitchen_pk'))
return self.queryset.all()
class OrderDetailView(generics.RetrieveUpdateDestroyAPIView):
...
def get_object(self):
if self.kwargs.get('kitchen_pk'):
return get_object_or_404(self.get_queryset(), kitchen_id=self.kwargs.get('kitchen_pk'), pk=self.kwargs.get('order_pk'))
return get_object_or_404(self.get_queryset(), pk=self.kwargs.get('order_pk'))
class ItemListView(generics.ListCreateAPIView):
...
def get_queryset(self):
if self.kwargs.get('kitchen_pk'):
return self.queryset.filter(kitchen_id=self.kwargs.get('kitchen_pk'))
return self.queryset.all()
class ItemDetailView(generics.RetrieveUpdateDestroyAPIView):
...
def get_object(self):
if self.kwargs.get('kitchen_pk'):
return get_object_or_404(self.get_queryset(), kitchen_id=self.kwargs.get('kitchen_pk'), pk=self.kwargs.get('item_pk'))
return get_object_or_404(self.get_queryset(), pk=self.kwargs.get('item_pk'))
В вашем urls.py:
urlpatterns = [
path('kitchens/', KitchenListView.as_view(), name='kitchens'),
path('kitchens/<int:pk>/', KitchenDetailView.as_view(), name='kitchen'),
path('kitchens/<int:kitchen_pk>/orders/', OrderListView.as_view(), name='kitchen_orders'),
path('kitchens/<int:kitchen_pk>/orders/<int:order_pk>/', OrderDetailView.as_view(), name='kitchen_order'),
path('kitchens/<int:kitchen_pk>/items/', ItemListView.as_view(), name='kitchen_items'),
path('kitchens/<int:kitchen_pk>/items/<int:item_pk>/', ItemDetailView.as_view(), name='kitchen_item'),
]
Я не знаю, получится ли это, но это начало!