Как сгенерировать аннотированное поле со списком значений в Django queryset?
Мне нужно составить расширенный запрос, который позволяет получить набор запросов, содержащий словари со строками для ключей и списки со всеми возможными значениями для значений. Вот что я получил:
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`, `.dictinct('partner')`, но ничего не помогает. Любые предложения будут оценены по достоинству, и большое спасибо за внимание.
UPD. Сопутствующая модель:
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}'
It is possible, but likely not a good idea. We can generate this with an ArrayAgg
expression [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].