按 drf 中价格总和设置的订单查询

问题描述 投票:0回答:1

我使用OrderingFilter,我有披萨模型通过多对多字段连接到pizzaprice模型,当我按desc或asc排序时,我没有得到预期的结果,如何通过价格总和或价格中的第一个数字获取查询集排序


模型.py

class Categorie(models.Model):
    name = models.CharField(max_length=60, default=[0])

    def __str__(self) -> str:
        return self.name

class PizzaPrice(models.Model):
    price = models.DecimalField(max_digits=8, decimal_places=2)

    def __str__(self) -> str:
        return str(self.price)
    
    class Meta:
        ordering = ['price']

class PizzaSize(models.Model):
    size = models.IntegerField()

    class Meta:
        ordering = ['size']

    def __str__(self) -> str:
        return str(self.size)

class Pizza(models.Model):
    name = models.CharField(max_length=60)
    imageUrl = models.CharField(max_length=150)
    category = models.ForeignKey(Categorie, default=1, on_delete=models.CASCADE)
    rating = models.IntegerField(choices=PIZZA_RATING, default=1)
    sizes = models.ManyToManyField(PizzaSize, blank=True, default=[0])
    prices = models.ManyToManyField(PizzaPrice, blank=True, default=[0])


    def __str__(self) -> str:
        return self.name

序列化器.py

class PizzaSerializer(serializers.ModelSerializer):
    category = serializers.CharField(source='category.name')
    sizes = serializers.SlugRelatedField(many=True, read_only=True, slug_field='size')
    prices = serializers.SlugRelatedField(many=True, read_only=True, slug_field='price')

    class Meta:
        model = Pizza
        fields = '__all__'

views.py

class PizzasList(generics.ListAPIView):
    queryset = Pizza.objects.all()
    serializer_class = PizzaSerializer
    pagination_class = PageNumberPagination
    filter_backends = [DjangoFilterBackend, OrderingFilter]

    filterset_fields = ['category']
    ordering_fields = ['rating', 'name', 'prices']

example of result: ordering by prices

我尝试了很多选择,但没有任何帮助

我刚开始学习Django不久,了解不多,希望您能帮忙解决这个问题,谢谢您的关注

want to get queryset order by total sum of prices or first number in prices

python django django-rest-framework django-filter
1个回答
0
投票

要按每个披萨的价格总和对查询集进行排序,您可以使用 Django 的

Sum
函数以及查询集中的
annotate
方法。以下是对
PizzasList
视图的修改示例:

from django.db.models import Sum

class PizzasList(generics.ListAPIView):
    queryset = Pizza.objects.annotate(total_price=Sum('prices__price'))
    serializer_class = PizzaSerializer
    pagination_class = PageNumberPagination
    filter_backends = [DjangoFilterBackend, OrderingFilter]

    filterset_fields = ['category']
    ordering_fields = ['rating', 'name', 'total_price']

此修改使用

annotate
向查询集中的每个披萨添加新字段
total_price
,表示与该披萨相关的价格总和。然后,您可以在 ordering_fields 中按
total_price
进行订购。请注意,这假设您要按升序排序。如果您想要降序排列,可以使用
-total_price
代替。

© www.soinside.com 2019 - 2024. All rights reserved.