我使用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']
我尝试了很多选择,但没有任何帮助
我刚开始学习Django不久,了解不多,希望您能帮忙解决这个问题,谢谢您的关注
要按每个披萨的价格总和对查询集进行排序,您可以使用 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
代替。