通过 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 中显示属于这个品牌的 Brand
和 amount 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】:只需将Count
与annotate
一起使用:
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_name
和 amount_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 模板损坏