有些事情在欺骗我。 我的任务是获取“类别vs品牌”列表,并查询“产品”模型。
说我们得到了这样的东西:
class Category(models.Model):
name = models.CharField(max_length=100) #examples: TVs, Monitors, HomeTheaters, Fridges
class Brand(models.Model):
name = models.CharField(max_length=100) #examples: Sony, LG, Apple
class Product(models.Model):
name = models.CharField(db_index=True, max_length=100)
category = models.ForeignKey(Category, on_delete=models.CASCADE)
brand = models.ForeignKey(Brand, on_delete=models.CASCADE)
我正在寻找的是一个可能返回如下内容的查询: {电视:[索尼,LG,苹果],显示器:[索尼,苹果]} 当然,它可以返回一个查询集,以后我可以将其转换为字典。
由于我无法以干净的方式完成此操作,因此我这样做:
categories = Category.objects.all()
products = Product.objects.select_related('category', 'brand').all()
categories_brands = {}
for category in categories:
categories_brands[category.name] = []
for product in products:
if product.brand.name not in categories_brands[product.category.name]:
category_brands[product.category.name].append(product.brand.name)
它确实起作用。但是那样的感觉很愚蠢。我曾尝试在模板标签中使用“注释”和“重新组合”解决方案,但无法使其正常工作。
除了这个问题之外……您是否对所有产品都拥有一个Model类,或者最好是冰箱类,电视类等等。我正在使用标签添加内容,例如冰箱的体积和显示器的大小,以便以后进行过滤。也许您的专家也可以给我一些建议。
谢谢。
魔咒。
答案 0 :(得分:2)
我们可以在单个查询中执行此操作,并为此使用itertools.groupby
[doc]:
from django.db.models import F
from itertools import groupby
from operator import itemgetter
qs = Product.objects.annotate(
category_name=F('category__name')
brand_name=F('brand__name')
).values('category_name', 'brand_name').order_by('category_name').distinct()
result = {
k: [v['brand_name'] for v in vs]
for k, vs in groupby(qs, itemgetter('category_name'))
}
因此,我们首先在数据库中查询category
和brand
,然后获得包含QuerySet
键和'category_name'
的{{1}}键,对于您的示例数据,它看起来像:
'brand_name'
然后,我们可以对查询集执行一次遍历,然后填充字典。
答案 1 :(得分:0)
类似这样的事情...
query = Product.objects.select_related('category', 'brand').all().query
query.group_by = ['category']
results = QuerySet(query=query, model=Product)