首页 > 解决方案 > 如何通过在 DRF 中以多对多关系查询另一个相关模型来获取模型对象列表

问题描述

模型.py:

class OrderItem(models.Model):
      image_number = models.CharField(max_length=20)
      title = models.CharField(max_length=20)
      image_url = models.URLField(max_length=200,null=True,blank=True)
      image_size = models.CharField(max_length=50)
      file_type = models.CharField(max_length=20)
      price = models.CharField(max_length=50)

     def __str__(self):
         return self.title

class Order(models.Model):
      order_status = (
          ('created','created'), 
          ('processing','processing'),
          ('orderd','orderd')
        )
      user = models.ForeignKey(CustomUser, on_delete=models.CASCADE, blank=True,null=True)
      items = models.ManyToManyField(OrderItem)
      order_status = models.CharField(choices=order_status,null=True,max_length=50)
      start_date = models.DateTimeField(auto_now_add=True)
      ordered_date = models.DateTimeField(auto_now_add=False,blank=True,null=True)

视图.py:

class AddtocartView(generics.CreateAPIView):
      authentication_classes = []
      permission_classes = []
      pagination_class = None
      queryset = OrderItem.objects.all()
      serializer_class = AddtocartSerializers

    def perform_create(self,serializer):
        new_order_item = serializer.save()
        user=CustomUser.objects.filter(id=self.kwargs['customer_id']).first() 

        try:
           orders_list = Order.objects.get(user=user)            
           orders_list.items.add(new_order_item) 
        except Order.DoesNotExist: 
            order = Order.objects.create(user=user) 
            order.items.add(new_order_item)  


       def __str__(self):
           return str(self.user)

网址.py:

 path('customer/<int:customer_id>/addtocart/',views.AddtocartView.as_view(),name='addtocart'),
 path('customer/<int:customer_id>/cart/',views.CartView.as_view(),name='cart'),   

在此处输入图像描述

一切正常。当我运行perform_createAPI 时,它会检查是否有现有created订单,如果有,则将其添加OrderItemitems,否则将创建订单。所以我的问题是当用户付款并Order.status更改为ordered我将如何获取订购的商品和购物车商品时。所以我在想我应该为每一个订单创建一个订单,OrderItem如果订单完成,它将更改为Order.statusordered否则将是created。这样,我将获取到created购物车和订购页面。关于我如何增强这种逻辑的任何建议?ordered

标签: djangopython-3.xdjango-rest-framework

解决方案


根据我在您的问题中的理解,您需要一个OrderItem根据相关Order状态检索 s 的 API。如果我弄错了,请在评论中纠正我

为了保持这个逻辑干净,

我建议你放弃Order为每个人创建一个的想法OrderItem

我相信对您有用的是,为 OrderItems 创建一个 API,让我们使用 调用它OrdersItemsListViewAPI,并基于 url 参数ex:Order进行过滤,这样您将只获得订单或订单,..etcOrder.status.../orders/items?status=createdcreatedordered

一个简单的例子

class OrdersItemsListViewAPI(generics.ListAPIView):
    """
    Return a list of all the products that the authenticated
    user has ever purchased, with optional filtering.
    """
    serializer_class = OrderItemSerializer

    def get_queryset(self):
        # You are using a custom user, make sure you get the custom user to do the query below.
        user = self.request.user
        status = self.request.query_params.get('status', None)
        # To make sure you are getting user's orders
        orders = Order.objects.filter(user=user)
        if status:
            # Filtering user's orders to get specific status
            orders = orders.filter(order_status=status)
        # Now get All OrderItems that belong to fetched orders.
        return OrderItem.objects.filter(order__in=orders)

更新:为了基于多个状态进行过滤,只需在查询参数中传递以逗号分隔的状态?status=created,ordered,并将它们提取到您的get_queryset方法中,如下所示。

...
    def get_queryset(self):
        # You are using a custom user, make sure you get the custom user to do the query below.
        user = self.request.user
        status = self.request.query_params.get('status', None)
        # To make sure you are getting user's orders
        orders = Order.objects.filter(user=user)
        if status:
            # Filtering user's orders to get specific status
            status = [s.strip() for s in status.split(',')]
            orders = orders.filter(order_status__in=status)
        # Now get All OrderItems that belong to fetched orders.
        return OrderItem.objects.filter(order__in=orders)

通过这种方式,您可以通过对控制器进行轻微修改来保持模型结构良好。

我已经在类似的场景中测试了这段代码,它运行良好。


推荐阅读