通过 ForeignKey 模型计算项目,Django 1.11

Posted

技术标签:

【中文标题】通过 ForeignKey 模型计算项目,Django 1.11【英文标题】:Count items via ForeignKey models, Django 1.11 【发布时间】:2018-09-29 03:25:10 【问题描述】:

我有 3 个模型:

class Product(TimeStampedModel):
    product_id = models.AutoField(primary_key=True, )
    brand = models.ForeignKey('Brand', related_name='products', on_delete=models.CASCADE)
    title = models.TextField(blank=False, null=False)
    '''...'''

class Brand(models.Model):
    brand_id = models.AutoField(primary_key=True,)
    brand_name = models.CharField(max_length=50)
    shops = models.ManyToManyField('Shop', related_name='shops')
    '''...'''

class Shop(models.Model):
    shop_id = models.AutoField(primary_key=True,)
    shop_name = models.CharField(max_length=30)
    '''...'''

我想在我的 html 中显示属于这个品牌的 Brandamount of products,就像这样:

FooBar    50
BazFoo    25
BarBob    12

我怎样才能以最快的方式做到这一点? 我试过了:

brands = 
for prod in products_list:
    brands[prod.brand.brand_name] = brands.get(prod.brand.brand_name, 0) + 1

但是这个迭代有时需要大约 7 秒(对于 20k+ 项的列表)。可能有某种 ORM 技巧或其他什么?P.S. 目前我得到这样的品牌,没有产品数量:

brands = Brand.objects.filter(shops__shop_name__in=[shop])

更新:就像 Ivan 在我更改的 cmets 中建议的那样:

    brands = Brand.objects.filter(shops__shop_name__in=[shop]).annotate(amount_of_products=Count('products'))
    brands = list(brands)

这减少了页面渲染时间,但该查询仍然需要 1.5-3 秒才能进入页面渲染。有什么办法可以让它更快吗?或者可能是任何其他解决方案,例如异步作业或数据库优化索引?

【问题讨论】:

【参考方案1】:

只需将Countannotate 一起使用:

from django.db.models import Count

brands = Brand.objects.filter(shops__shop_name__in=[shop]).annotate(amount_of_products=Count('products')).values('brand_name', 'amount_of_products')

【讨论】:

如果我使用它 - 我收到错误:/search/ 处的 FieldError 无法将关键字“产品”解析到字段中。选项包括:brand_id、brand_name、类别、产品、促销、商店 如果我使用这种方法 - 运行时间增加到 15+ 秒:/ 嗯,看来我找到了窍门——brands = list(brands) 最终将页面渲染时间减少到 5-6 秒。比开始时要好,但仍然要慢。让它工作得更快是真的吗? values() 应该让它更快。我更新了答案。确保在您的 html 模板中访问 brand_nameamount_of_products【参考方案2】:

最好使用ORM

from django.db.models import Count
Product.objects.values('brand__brand_name').annotate(count=Count('brand__brand_name'))

【讨论】:

以上是关于通过 ForeignKey 模型计算项目,Django 1.11的主要内容,如果未能解决你的问题,请参考以下文章

如何在 django 的单个视图中显示多个 ForeignKey 过滤项目?

模型字段类型从 CharField 更改为 ForeignKey 时 Django 模板损坏

Django:ForeignKey(models) 到不可见的模型?

按 foreignKey 关系中的字段过滤

Django ForeignKey 表单字段小部件

尝试使用子查询计算时差时出错