如何在Django查询集中生成带值列表的注释字段?

1 投票
1 回答
35 浏览
提问于 2025-04-14 17:51

我需要写一个复杂的查询,让我能得到一个包含字典的查询结果,这些字典的键是字符串,值是所有可能的值组成的列表。下面是我现在的代码:

In [26]: Offer.objects.values('partner', 'partner_id')

Out[26]: <QuerySet [{'partner': 'xex', 'partner_id': 'x_999'}, {'partner': 'xex', 'partner_id': 'x_888'}, {'partner': 'quiup', 'partner_id': 'q_888'}, {'partner': 'quiup', 'partner_id': 'q_777'}]>

这是我想要得到的结果:

<QuerySet [{'partner': 'xex', 'partner_ids': ['x_999', 'x_888']}, {'partner': 'quiup', 'partner_ids': ['q_888', 'q_777']}

我试过使用注解、F表达式、`Value`、`.distinct('partner')`,但都没有让我更接近目标。任何建议都非常感谢,感谢你的关注。

更新:相关的模型如下:

class Offer(models.Model):
partner = models.CharField(
    verbose_name='Partner',
    max_length=50
)
partner_id = models.CharField(
    verbose_name='Partner ID',
    max_length=100,
    unique=True,
    null=False,
    blank=False,
    default=''
)

def __str__(self):
    return f'{self.partner} - {self.partner_id}'

1 个回答

0

这是可能的,但可能不是个好主意。我们可以用一个ArrayAgg表达式来生成这个内容。[Django-doc]

from django.contrib.postgres.aggregates import ArrayAgg

Offer.objects.values('partner').annotate(
    partners_ids=ArrayAgg('partner_id')
).order_by('partner')

因为partner看起来是一个分类,所以最好用一个ForeignKey来关联其他东西,比如:

class PartnerType(models.Model):
    id = models.CharField(primary_key=True)


class Partner(models.Model):
    pass


class Offer(models.Model):
    partner_type = models.ForeignKey(PartnerType, on_delete=models.PROTECT)
    parter = models.ForeignKey(Partner, on_delete=models.PROTECT)

在这种情况下,我们可以使用:

PartnerType.objects.prefech_related('offer_set')

这样做还可以避免我们出现原始迷恋 [refactoring.guru]的问题。

撰写回答