首页 > 解决方案 > 检索每个客户的最后一个订单

问题描述

我正在为商店创建一个 API。在那里我应该退回每个客户的最后一个订单。这是我的 Customer 和 Order 模型的代码。

class Customer(models.Model):
    name = models.CharField(max_length=14, null=True)
    country = models.CharField(max_length=3, null=True)
    address = models.TextField()
    phone = models.CharField(max_length=50)

class Order(models.Model):
    date = models.DateField(null=True)
    customer = models.ForeignKey(Customer, on_delete=models.CASCADE)

这是序列化程序.py

class CustomerSerializer(serializers.ModelSerializer):
    class Meta:
        model = Customer
        fields = ['id', 'name', 'country', 'address', 'phone']

class OrderSerializer(serializers.ModelSerializer):
    customer = CustomerSerializer()

    class Meta:
        model = Order
        fields = ['id', 'date', 'customer']

我通过以下方式使用 Django ORM 获得每个客户的最后一个订单

@api_view(('GET',))
def customers_last_orders(request):
    orders = models.Order.objects.all().order_by('customer', '-date').distinct()
    serializer = serializers.OrderSerializer(orders, many=True)

    return Response(serializer.data)

但是我从这个视图中得到了所有顺序的订单。

标签: djangodjango-rest-framework

解决方案


你 order by customer, then -date,所以它首先申请 order by customer。您的查询集应该是:

orders = models.Order.objects.all().order_by('-date').distinct()

数据将返回订单,而不是客户


但是如果要获取客户列表中是否有最新的订单对象,应该是:

模型.py

class Order(models.Model):
    date = models.DateField(null=True)
    customer = models.ForeignKey(Customer, on_delete=models.CASCADE, related_name='orders')

序列化程序.py

class OrderSerializer(serializers.ModelSerializer):

    class Meta:
        model = Order
        fields = ['id', 'date']

class CustomerSerializer(serializers.ModelSerializer):
    orders = serializers.SerializerMethodField()
    class Meta:
        model = Customer
        fields = ['id', 'name', 'country', 'address', 'phone', 'orders',]

        def get_orders(self, instance):
            """
            Custom to order Order items
            """

            orders = instance.orders.order_by('-date') 
            # Update to `orders = instance.orders.order_by('-date')[:1]` if you just need only one latest order item.
            return OrderSerializer(orders, many=True).data

视图集.py

@api_view(('GET',))
def customers_last_orders(request):
    customers = Customer.objects.all().order_by('...')
    serializer = serializers.CustomerSerializer(customers, many=True)

    # Order by customer's orders
    data = sorted(serializer.data, key=lambda item: item['orders'][0]['date'], reverse=True)
    return Response(data)

尚未测试,但它应该可以工作。我有点担心sorted(...)^^


推荐阅读