Django ORM如何获取平均值

3

models.py

class Testimonials(models.Model):
    RATING = (
            (1,'Очень плохо'),
            (2,'Плохо'),
            (3,'Средне'),
            (4,'Хорошо'),
            (5,'Очень хорошо'),
        )
    EXP = (
            (1, 'Не указан'),
            (2, 'Один день'),
            (3, 'Одна неделя'),
            (4, 'Один месяц'),
            (5, 'Более года'),
        )
    user = models.OneToOneField(User)
    publish = models.BooleanField(default=False)
    created = models.DateTimeField(auto_now_add=True)
    testimonial = models.TextField(max_length=1000, null=True, blank=True)
    rating_sup = models.IntegerField(choices=RATING, max_length=1, null=True, blank=True)
    rating_stability = models.IntegerField(choices=RATING, max_length=1, null=True, blank=True)
    rating_trust = models.IntegerField(choices=RATING, max_length=1, null=True, blank=True)
    experience = models.IntegerField(choices=EXP, max_length=1, default=1, blank=True)
    affiliate = models.ForeignKey(Affiliate, null=True, blank=True)
    offer = models.ForeignKey(Offer, null=True, blank=True)

我的查询集是:

Affiliate.objects.get(pk=2).testimonials_set.all().aggregate(Avg('rating_trust'), Avg('rating_sup'), Avg('rating_stability'))

结果:

{'rating_stability__avg': 3.0, 'rating_trust__avg': None, 'rating_sup__avg': 4.0}

如何计算三个值的平均数 ((3+4)/2=3.5)


你的意思是如何计算它? - doru
不,我需要获取3个不同列的平均值,然后按该值排序。 - Савостьянов Максим
如果输入的是英文,我可以把它翻译成中文。 - Савостьянов Максим
2个回答

2

1
问题在于如果'rating_stability'或'rating_sup'中有一个为NULL,那么它们的和也将为NULL,这将导致错误的结果。 - Antoine Pinsard

1
你可以向想要进行聚合的模型字段添加一个 default=0 值:
rating_sup = models.IntegerField(choices=RATING, max_length=1, blank=True, default=0)
rating_stability = models.IntegerField(choices=RATING, max_length=1, blank=True, default=0)
rating_trust = models.IntegerField(choices=RATING, max_length=1, blank=True, default=0)

然后您可以使用 Avg 聚合所有三个字段

Affiliate.testimonials_set.all().aggregate(avr=Avg(F('rating_trust') + F('rating_sup') + F('rating_stability'))).order_by('avr')

Avg只接受一个位置参数。https://github.com/django/django/blob/1.9.2/django/db/models/aggregates.py#L76 - Antoine Pinsard
我认为将default=0设置为默认值并不能防止F('...')变成None。是这样吗? - Antoine Pinsard
可以了,谢谢。但是 AVR 返回 2.3,我需要得到 3.5,应该忽略 None 值。 - Савостьянов Максим
我刚刚更改了模型并将默认值设置为0,对于Affiliate.objects.get(pk=2).testimonials_set.all().aggregate(avr=Avg(F('rating_trust') + F('rating_sup') + F('rating_stability')))返回了None。 - Савостьянов Максим
是的,如果我将 null=False 设为 True,然后尝试在数据库中添加记录,那么我会得到一个错误:invalid literal for int() with base 10: ''。 - Савостьянов Максим
显示剩余6条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接