我有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 :
brands = Brand.objects.filter(shops__shop_name__in=[shop]).annotate(amount_of_products=Count('products'))
brands = list(brands)
这减少了页面呈现的时间,但是该查询仍然需要1.5-3秒才能进行页面呈现。有没有选择让它更快?或者可以是任何其他解决方案,如异步作业或数据库优化索引?
答案 0 :(得分:0)
只需将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')
答案 1 :(得分:0)
最好使用ORM
from django.db.models import Count
Product.objects.values('brand__brand_name').annotate(count=Count('brand__brand_name'))