Как получить список объектов модели, запросив другую связанную модель в отношениях «многие ко многим» в DRF - PullRequest
0 голосов
/ 22 января 2020

models.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)

views.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)

urls.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'),   

enter image description here

Все работает нормально. когда я запускаю perform_create API, он проверяет, существует ли существующий ордер created и, если он есть, добавляет OrderItem к items, иначе он создаст ордер. Поэтому моя проблема в том, что когда пользователь делает платеж, а Order.status меняется на ordered, то как я собираюсь получить заказанные товары и товар в корзине. Поэтому я подумал, что должен создать заказ для каждого OrderItem, тогда, если заказ будет выполнен, он изменит Order.status на ordered, в противном случае это будет created. Таким образом я получу created в корзину и ordered в Заказанную страницу . Любое предложение о том, как я могу улучшить эту логику c?

1 Ответ

1 голос
/ 22 января 2020

Из того, что я понял в вашем вопросе, вы хотите API, который извлекает OrderItem s на основе их связанного статуса Order. Исправьте меня в комментариях, если я ошибся

Чтобы сохранить эти логику c чистыми,

Я рекомендую вам go эту идею создания Order для каждого OrderItem

Я думаю, что это сработает для вас, это создание API для OrderItems, давайте назовем его OrdersItemsListViewAPI с Order и будем выполнять фильтрацию на основе Order.status на основе URL-параметра ex: .../orders/items?status=created, таким образом вы получите только created заказов или ordered заказов, ..et c

Простой пример this

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)

Таким образом, вы держите свои модели хорошо структурированными с небольшой модификацией на вашем контроллере.

Я тестировал этот код в похожем сценарии, и работает отлично.

...