python - Django 中 QuerySet 中特定列的平均重复项

标签 python django duplicates django-queryset average

我正在使用一个 Django 模型,如下所示:

class FinancialAid(models.Model):
    RECEIVED_EVERY = (("J", "Jours"),
        ("S", "Semaines"),
        ("M", "Mois"))
    ID = models.AutoField(primary_key=True)
    Name = models.CharField(max_length=100, null=True, blank=True)
    Value = models.IntegerField(null=True, blank=True, default=-1)
    ReceivedEvery = models.CharField(max_length=15, null=True, blank=True, choices=RECEIVED_EVERY)
    Exchange = models.ForeignKey('Exchange', on_delete=models.CASCADE)

我能够访问我想要的信息,但有一个问题,因为我的 QuerySet 中的 NameReceivedEvery 列经常有重复项,但并不总是存在Value,并且绝不在Exchange上。

假设我扩展了以下查询集:

financial_aid_qs = [
    (ID=1, Name="Aid1", Value=100, ReceivedEvery="M", Exchange=Exchange.objects.get(pk=1)),
    (ID=2, Name="Aid2", Value=200, ReceivedEvery="S", Exchange=Exchange.objects.get(pk=2)),
    (ID=3, Name="Aid1", Value=150, ReceivedEvery="M", Exchange=Exchange.objects.get(pk=3)),
    (ID=4, Name="Aid3", Value=100, ReceivedEvery="M", Exchange=Exchange.objects.get(pk=4))
]

如您所见,索引 1 和 3 具有相同的 NameReceivedEvery。我想要做的是获取一个 QuerySet(或 ValuesQuerySet,尽管我似乎还记得这一点已被删除),它将包含所有不同的 FinancialAid 对象的 Name 并计算具有相同 Name< 的 FinancialAid 对象的 Value 的平均值。理想情况下,它会考虑到即使 Name 相同,ReceivedEvery 也可能不同的事实(这都是平均值,因此不需要完美,这就是为什么因此,一个月就是 30 天或 4 周)。

有了这一切,结果应该如下所示:

financial_aid_qs = [
    (Name="Aid1", Value=125, ReceivedEvery="M"),
    (Name="Aid2", Value=200, ReceivedEvery="S"),
    (Name="Aid3", Value=100, ReceivedEvery="M")
]

如您所见,对于 Aid1,该值已从 100 和 150 平均为 125,其他 Aids 未进行修改。

最佳答案

使用values()聚合分组查询,例如:

financial_aid_qs = FinancialAid.objects.values("Name").annotate(avg_value=Avg("Value"))

这将返回字典的查询集(执行时为列表):

financial_aid_qs = [
    {'Name': "Aid1", 'avg_value': 125},
    {'Name': "Aid2", 'avg_value': 200},
    ...
]

如果您还想通过 ReceivedEvery 进行区分,那么您只需按这两个值进行分组即可:

financial_aid_qs = FinancialAid.objects.values('Name', 'ReceivedEvery').annotate(...)

>>> [{'Name': "Aid1", 'ReceivedEvery': "M", 'avg_value': 125}, 
     {'Name': "Aid1", 'ReceivedEvery': "S", 'avg_value': 200}, ...]

在这里,每周和每月的捐款将针对同一“姓名”分开。

使用 conditional expression依赖他人创造新的值(value):

financial_aid_qs = FinancialAid.objects.annotate(
    factor=Case(
        When(ReceivedEvery="S", then=Value(4)),
        When(ReceivedEvery="M", then=Value(1)),
        output_field=IntegerField()
    )).annotate(
        total=F('factor')*F('Value')
    ).values('Name').annotate(
        avg_value=Avg('total')
    )

关于python - Django 中 QuerySet 中特定列的平均重复项,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58910772/

相关文章:

Python输入单个字符不用回车

python - 将 django 中的键值更改为列表

api - YouTube API获取Feed时忽略重复项

mysql - Codeigniter 中的 mysql 错误表单验证

excel - 从 Excel 电子表格中删除包含重复数据的行?

python - 使用外部定义的函数修改模块全局变量

python - 如果函数给出的值非常接近 0,则对函数内部的数字进行舍入

python - 我可以关闭在 Python 中使用 subprocess.Popen 打开的 CMD 窗口吗?

django - NoReverseMatch Django URL

python - Django 'next' 重定向用于登录和新用户