Django查询ForeignKeys返回“分组依据”列表

时间:2018-09-13 20:56:47

标签: python django

有些事情在欺骗我。 我的任务是获取“类别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类,或者最好是冰箱类,电视类等等。我正在使用标签添加内容,例如冰箱的体积和显示器的大小,以便以后进行过滤。也许您的专家也可以给我一些建议。

谢谢。

魔咒。

2 个答案:

答案 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'))
}

因此,我们首先在数据库中查询categorybrand,然后获得包含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)