如何在没有路由器的情况下在Django Rest Framework(DRF)RetrieveUpdateDestroy



我正在使用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视图或视图集会更好。

提前感谢。

首先,我假设您有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'),
]

我不知道它是否可行,但这只是一个开始!

最新更新