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

时间:2018-04-18 19:07:06

标签: html django postgresql django-models django-templates

我有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

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

这减少了页面呈现的时间,但是该查询仍然需要1.5-3秒才能进行页面呈现。有没有选择让它更快?或者可以是任何其他解决方案,如异步作业或数据库优化索引?

2 个答案:

答案 0 :(得分:0)

只需将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')

答案 1 :(得分:0)

最好使用ORM

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