如何在没有路由器的情况下在 Django Rest Framework (DRF) RetrieveUpdateDestroyAPIView 中嵌套 URL 路由
How to Nest URL routes in Django Rest Framework (DRF) RetrieveUpdateDestroyAPIView without router
我正在使用 Django rest 框架和 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 视图或视图集会更好,因为我的项目是一个大型项目。
提前致谢。
首先,我假设您有订单视图和商品视图;在你的两个观点中试试这个:
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'),
]
我不知道它是否有效,但这是一个开始!
我正在使用 Django rest 框架和 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 视图或视图集会更好,因为我的项目是一个大型项目。
提前致谢。
首先,我假设您有订单视图和商品视图;在你的两个观点中试试这个:
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'),
]
我不知道它是否有效,但这是一个开始!