【问题标题】:Why my queryset changes size after I evaluate it in Django?为什么我的查询集在 Django 中评估后会改变大小?
【发布时间】:2021-08-10 23:24:13
【问题描述】:

我有一个简单的模型:

class Expense(models.Model):
    ...
    price = models.DecimalField(decimal_places=2, max_digits=6)
    is_fixed = models.BooleanField(default=False)

我正在尝试对 group_by 和聚合进行简单查询:

>>> from expenses.models import Expense
>>> from django.db.models import Sum
>>> qs = Expense.objects.values('is_fixed').annotate(total=Sum('price'))

我预计qs 会有两条记录:

>>> qs.count()
2

但是当我评估它时,它返回 9!

>>> len(qs)
9

评估后,count 也开始返回 9:

>>> qs.count()
9

为了进一步说明:

>>> qs = Expense.objects.values('is_fixed').annotate(total=Sum('price'))
>>> qs.count() == len(qs)
False
>>> len(qs) == qs.count()
True
>>> qs = Expense.objects.values('is_fixed').annotate(total=Sum('price'))
>>> len(qs) == qs.count()
True

我不知道是什么导致了这种“异常”。你认为它可能是什么?

更新: 以下是 bdbd 要求的一些数据:

[
    {
        "price": 9.11,
        "category": "HOUSE",
        "created_at": "14/08/2021",
        "source": "BANK_SLIP",
        "is_fixed": True
    },
    {
        "price": 600.0,
        "category": "GIFT",
        "created_at": "09/08/2021",
        "source": "BANK_TRANSFER",
        "is_fixed": False
    },
    {
        "price": 10.5,
        "category": "FOOD",
        "created_at": "08/08/2021",
        "source": "SETTLE_UP",
        "is_fixed": False
    },
    {
        "price": 28.0,
        "category": "GIFT",
        "created_at": "08/08/2021",
        "source": "SETTLE_UP",
        "is_fixed": False
    },
    {
        "price": 20.44,
        "category": "SUPERMARKET",
        "created_at": "07/08/2021",
        "source": "SETTLE_UP",
        "is_fixed": False
    },
    {
        "price": 8.5,
        "category": "SUPERMARKET",
        "created_at": "06/08/2021",
        "source": "CREDIT_CARD",
        "is_fixed": False
    },
    {
        "price": 726.0,
        "category": "HOUSE",
        "created_at": "04/08/2021",
        "source": "BANK_SLIP",
        "is_fixed": True
    },
    {
        "price": 34.8,
        "category": "HOUSE",
        "created_at": "04/08/2021",
        "source": "BANK_SLIP",
        "is_fixed": True
    },
    {
        "price": 43.97,
        "category": "HOUSE",
        "created_at": "04/08/2021",
        "source": "MONEY",
        "is_fixed": True
    },
    {
        "price": 4.09,
        "category": "SUPERMARKET",
        "created_at": "04/08/2021",
        "source": "CREDIT_CARD",
        "is_fixed": False
    },
    {
        "price": 168.0,
        "category": "OTHER",
        "created_at": "04/08/2021",
        "source": "BANK_SLIP",
        "is_fixed": False
    },
    {
        "price": 23.4,
        "category": "FOOD",
        "created_at": "04/08/2021",
        "source": "SETTLE_UP",
        "is_fixed": False
    },
    {
        "price": 169.0,
        "category": "OTHER",
        "created_at": "03/08/2021",
        "source": "BANK_SLIP",
        "is_fixed": False
    },
    {
        "price": 9.81,
        "category": "SUPERMARKET",
        "created_at": "03/08/2021",
        "source": "CREDIT_CARD",
        "is_fixed": False
    },
    {
        "price": 100.0,
        "category": "RECREATION",
        "created_at": "03/08/2021",
        "source": "MONEY",
        "is_fixed": False
    },
    {
        "price": 10.0,
        "category": "SUPERMARKET",
        "created_at": "02/08/2021",
        "source": "CREDIT_CARD",
        "is_fixed": False
    }
]

【问题讨论】:

  • 你能分享一些数据吗?
  • @bdbd 我只是更新问题。

标签: python django django-queryset


【解决方案1】:

问题是因为我在Meta 上设置了ordering

class Meta:
    ordering = ("-created_at",)

在 order_by 子句上设置正确的字段解决了这个问题:

>>> qs = Expense.objects.order_by("is_fixed").values("is_fixed").annotate(total=Sum("price"))
>>> len(qs) == qs.count()
True
>>> qs = Expense.objects.order_by("is_fixed").values("is_fixed").annotate(total=Sum("price"))
>>> qs.count() == len(qs)
True

【讨论】:

  • 我想知道为什么排序会改变查询集中的记录数?
  • @JohnGordon 根据 django 文档:“同样,如果您使用 values() 查询来限制所选列,则仍将涉及任何 order_by() (或默认模型排序)中使用的列并可能影响结果的唯一性。” docs.djangoproject.com/en/3.2/ref/models/querysets
猜你喜欢
  • 1970-01-01
  • 2018-02-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-01-21
  • 2011-07-18
  • 2019-06-04
相关资源
最近更新 更多