【问题标题】:Django model with Charfield Count and Zero values具有 Charfield 计数和零值的 Django 模型
【发布时间】:2021-06-11 04:35:18
【问题描述】:

我有一个 Django 数据库模型,它有一些属性,其中之一是带有选项的 Charfield“类别”。 我现在想用每个类别的行数来注释这个模型的查询集。问题是,我知道这样做的方式,只有查询集中存在的类别被计算在内,但我想要一个查询集,其中所有类别都用计数注释(如果没有此类别的行,则为 0)。

这就是我现在正在做的事情:

Model.objects.all().values('category').annotate(total=Count('category'))

有没有办法显示所有类别,包括计数为 0 的类别?

【问题讨论】:

  • 那么您将如何计算不存在的Categorys?
  • 如果选择是固定的,并且您不觉得需要创建另一个模型,请在类似问题上查看我的 answer
  • @AbdulAzizBarkat:我的一位教授曾经说过:“编程中只有三个有意义的常数:零、一和多”。他的意思是,通常将事物设置为固定的基数最终会导致很多麻烦:)。它通常还会产生额外的问题,例如 数据重复,因为现在我们在每条记录中重复相同的类别。如果我们以后想重命名该类别,可能会让人很头疼。
  • @WillemVanOnsem 有很好的建议。 :) 从来没有这样想过。由于我曾经遇到过类似的问题,上述答案中的方法实际上也是由我创建的,现在我回头看这是我的糟糕设计。
  • @AbdulAzizBarkat:好吧+1 :)

标签: python django


【解决方案1】:

您不能计算不存在的类别,因为,嗯……这些不存在。 choices 甚至没有传输到数据库中。

CharFieldchoices 一起使用并不是理想的建模方式。通常最好先创建一个模型Category,然后再创建一个MyModelForeignKey [Django-doc],将MyModel 对象链接到Category,所以:

class Category(models.Model):
    name = models.CharField(max_length=128)

    def __str__(self):
        return self.name

class MyModel(models.Model):
    category = models.ForeignKey(Category, on_delete=models.PROTECT)

然后我们可以创建如下类别:

Category.objects.bulk_create(
    Category(name='technology'),
    Category(name='art'),
    Category(name='science')
)

如果我们随后将MyModel 对象链接到这些Categorys,我们可以用MyModels 的数量注释Category

from django.db.models import Count

Category.objects.annotate(
    num_mymodel=Count('mymodel')
)

这里由 this 查询集产生的 Categorys 将有一个额外的属性 .num_mymodel 与链接的 MyModel 对象的数量。由于执行了LEFT OUTER JOIN,对于没有任何MyModels 的Categorys,它将使用0

【讨论】:

  • 好的,谢谢。我想最好把所有东西都放在一个模型中。
猜你喜欢
  • 2017-08-17
  • 2013-04-22
  • 2011-12-24
  • 2014-05-14
  • 2018-12-08
  • 2016-08-10
  • 1970-01-01
  • 1970-01-01
  • 2018-10-10
相关资源
最近更新 更多