【问题标题】:How to count items in a foreign key?如何计算外键中的项目?
【发布时间】:2019-02-24 09:37:02
【问题描述】:

我正在使用 django 制作博客应用程序...

这是我的model.py

class categories(models.Model):
    Title = models.CharField(max_length=40)

class Blog(models.Model):
    User = models.ForeignKey(settings.AUTH_USER_MODEL,on_delete=models.CASCADE,null=True,blank=True)
    Date = models.DateTimeField(default=datetime.now)
    Blog_title = models.CharField(max_length=255)
    likes = models.ManyToManyField(settings.AUTH_USER_MODEL,related_name='likes',blank=True)
    Description = RichTextUploadingField(blank=True, null=True,config_name='special')
    Blog_image = models.ImageField(upload_to='blog_image', null=True, blank=True)
    Category = models.ForeignKey(categories,on_delete=models.CASCADE,related_name='Categories')

我想知道如何计算特定类别下的博客总数?

我想跟踪所有类别的特定计数率...

【问题讨论】:

标签: django django-models foreign-keys


【解决方案1】:

如果要统计每个Category有多少个Blogs,我们可以在Category上做个注解:

from django.db.models import Count

Category.objects.annotate(
    num_blogs=Count('Categories')
)

但是(如后所述),使用categories作为相关名称是完全错误的,应该重命名为blogs,因为这是反向关系,在这种情况下查询是:

from django.db.models import Count

Category.objects.annotate(
    num_blogs=Count('blogs')
)

结果是一个包含所有Category 对象的QuerySet,每个Category 对象都有一个属性num_blogs,其中包含与此类别相关的博客数量。

通过注释这样做的好处是可以避免“N+1 问题”:这里我们仍然执行 one 查询,而不是 one 查询类别,n 查询以获得该特定类别的博客计数。在 MySQL 中,查询将如下所示:

SELECT category.*, COUNT(blog.id)
FROM category
LEFT OUTER JOIN blog ON blog.category_id = category.id
GROUP BY category.id

注意:Python 中的属性通常以小写字母开头(并在单词之间使用下划线),因此blog_titlecategory 而不是Blog_titleCategory

 

注意related_name是你给reverse关系的对象起的名字,所以category = ForeignKey(..)related_name应该是'blogs' ,而不是'categories'

【讨论】:

    【解决方案2】:
    [{"category_title":category.Title, "count":Blog.objects.filter(Category=category).count()} for category in categories.objects.all()]
    

    这将给出一个带有类别标题及其相应计数的字典列表

    【讨论】:

      【解决方案3】:
      for title in categories.objects.all():
          Blog.objects.filter(Category__Title=a.title).count()
      

      这将满足您的需求。

      【讨论】:

      • 正确答案,虽然应该是Category__Title
      • 这仅适用于一个对象...不是全部...您有针对所有对象的解决方案吗???
      • 这肯定会工作...但仅适用于类别列表中的一个类别...我希望它适用于所有类别 django 会自动指定它们的计数...
      • 这将适用于所有类别,而不是一个,一旦尝试并检查
      【解决方案4】:

      您也可以使用类别模型。

      Categories.objects.filter(Title="someName").Categories.all().count()
      

      【讨论】:

      • 这仅适用于一个对象...不是全部...您对类别中的所有对象有任何解决方案吗???
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-02-27
      • 2021-09-15
      • 2014-02-09
      • 2018-02-08
      • 1970-01-01
      • 2021-10-25
      • 1970-01-01
      相关资源
      最近更新 更多