Django注释,将多个相关值组合到同一个实例上

时间:2019-05-10 17:45:48

标签: python django python-3.x django-queryset django-annotate

我有一个具有以下型号的django应用程序:

class Person(models.Model):
    first_name = models.CharField(max_length=100)
    last_name = models.CharField(max_length=100)

class Job(models.Model):
    title = models.CharField(max_length=100)

class PersonJob(models.Model):
    person = models.ForeignKey(Person, related_name='person_jobs')
    job = models.ForeignKey(Job, related_name='person_jobs')
    is_active = models.BooleanField()

多个Person实例可以一次容纳相同的作业。我有一个Job查询集,正在尝试注释或通过其他方法将具有该工作的每个人的姓名附加到查询集中的每个项目上。我希望能够遍历queryset并获取那些名称,而无需对每个项目进行额外的查询。我得到的最接近的是:

 qs = Job.objects.all().annotate(first_names='person_jobs__person__first_name')
.annotate(last_names='person_jobs__person__last_name') 

这将根据需要将名称存储在Job实例上;但是,如果一个作业中有多个人,则查询集将在其中包含同一作业的多个副本,每个副本都有一个人的名字。相反,我只需要在查询集中只有一个给定Job的实例,该实例中包含所有人员的名字。我不在乎这些值如何组合和存储。列表,带分隔符的char字段或其他任何标准数据类型都可以。

我正在使用Django 2.1和Postgres 10.3。我强烈希望不要使用任何Postgres特定功能。

1 个答案:

答案 0 :(得分:0)

您可以使用ArrayAggStringAgg

from django.contrib.postgres.aggregates import ArrayAgg, StringAgg  


Job.objects.all().annotate(first_names=StringAgg('person_jobs__person__first_name', delimiter=',')

Job.objects.all().annotate(people=ArrayAgg('person_jobs__person__first_name'))