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

标签 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 查询集,并尝试注释或通过其他方法将从事该工作的每个人的姓名附加到查询集中的每个项目上。我希望能够循环查询集并获取这些名称,而无需对每个项目进行额外的查询。我得到的最接近的是:

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

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

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

最佳答案

您可以使用 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'))

关于python - Django注释,将多个相关值组合到同一个实例上,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56082507/

相关文章:

python - 转置多级索引 pandas

Python多处理: TypeError: 'Queue' object is not iterable

python - 如何在python( Tornado )中的websocket循环之外运行函数

python - 如何阻止 CharField 在新的发布请求后清除其数据?

python - django spotify api python http发布500错误

shell - 如何使用 tox 运行自定义命令而不在 tox.ini 中指定它?

python - 如何将模块用作包的一部分并作为可直接执行的脚本?

Python 多线程性能 - 使用 C++ 代替?

python - Django 上传到动态(ish)文件名

python - QThread 没有完成