如何使用django drf泛型视图列出所有对象并检索单个对象

fhity93d  于 2022-12-14  发布在  Go
关注(0)|答案(1)|浏览(131)

我正在尝试创建一个基于类的视图,用于检索、列出并创建我所有的订单。我已经得到创建和检索的工作,但上市是给一些问题。我正在使用DRF泛型视图来扩展我的视图,并已添加泛型。listApiView到我的类。一旦我添加了这个,但我的检索路线开始行动不寻常。当我只想要一个特定的订单时,它会返回给我一个所有订单的列表。
我尝试只将泛型.ListApiView添加到我的类中,并覆盖list和get_queryset函数,但这刚刚开始影响我的检索视图。

class Order(generics.ListAPIView, generics.CreateAPIView, generics.RetrieveAPIView):
    permission_classes = (permissions.IsAuthenticated,)
    serializer_class = addOrderSerializer
    
    def get_queryset(self, **kwargs):
        user = self.request.user
        return Order.objects.filter(user=user)

    def get_object(self):
        pk = self.kwargs['pk']
        obj = Order.objects.get(pk=pk)
        return obj

    def get_item_serializer(self, *args, **kwargs):
        return addItemSerializer(*args, **kwargs)

    def get_shipping_serializer(self, *args, **kwargs):
        return addShippingSerializer(*args, **kwargs)

    def create(self, request, *args, **kwargs):
        user = request.user
        data = request.data
        orderItems = data.get('orderItems')
        print(data)
        if not bool(orderItems):
            return Response('No Order Items', status=status.HTTP_400_BAD_REQUEST)
        else:
            # TODO - Create Order
            orderSerializer = self.get_serializer(data=data)
            orderSerializer.is_valid(raise_exception=True)
            order = orderSerializer.save(user=user)
            
            # TODO - Create Shipping Address
            shippingSerializer = self.get_shipping_serializer(data=data)  
            shippingSerializer.is_valid(raise_exception=True)
            shippingSerializer.save(order=order)

            # TODO - Create Order Items and Set Order <> OrderItem Relationship
            for item in orderItems:
                product = Product.objects.get(pk=item['product'])
                itemSerializer = self.get_item_serializer(data=item)
                itemSerializer.is_valid(raise_exception=True)
                item = itemSerializer.save(order=order, product=product)
    #         # TODO - Update Product CountInStock
                product.countInStock -= item.qty
                product.save()
            
        return Response(data=orderSerializer.data)

    def retrieve(self, request, *args, **kwargs):
        instance = self.get_object()
        s = self.get_serializer(instance=instance)
        return Response(data=s.data)

    def list(self, request, *args, **kwargs):
        qs = self.get_queryset()
        s = self.get_serializer(qs, many=True)
        return Response(s.data)
from django.contrib import admin
from django.urls import path, include
from .. import views

urlpatterns = [
    path('', views.Order.as_view()),
    path('add/', views.Order.as_view()),
    path('<int:pk>/', views.Order.as_view({'get':'retrieve'})),
]

总之,我的视图的列表功能现在可以工作了,但是它扰乱了我的检索功能,所以即使我在url中添加了pk,检索函数也只返回一个列表。

cgh8pdjw

cgh8pdjw1#

为了更清楚起见,你能把你的www.example.com也贴出来吗urls.py?
目前根据您的问题,我看到的问题如下:
1.您正在调用类“Order”,以便使用某种url模式(例如path/int:pk)来检索方法--这是一个GET请求
1.您还可以使用一些url模式(例如path/ --这是一个Get请求)为列表方法调用同一个类“Order
问题是Retrieve和List泛型API都有一个GET方法:添加片段:

结论:

**这是python继承中方法解析顺序的一个示例。**因此,即使您尝试调用GET方法进行检索,它也会调用LIST API的GET方法,因为在您的类定义类Order(generics.ListAPIView、generics.CreateAPIView、generics.RetrieveAPIView)中,您首先继承了ListAPIView。

解决方案:
1.你应该把这些类分开,例如:列表创建API视图、检索更新销毁API视图
或者:您还可以按照下面的stackoverflow应答将GET请求路由到同一类中的特定方法:
Multiple get methods in same class in Django views

相关问题