Django object.filters.order_by() 多次返回相同的实例,当我排序的字段是"many to many"



问题是:我有两个模型ContactTitle

  • 代表一个人
  • 标题
  • 表示职位名称

一个人可以有多个职称,两个模型通过多对多关系关联(见下面的模型)。

问题是,出于某种原因,当我做这个查询contacts = Contact.objects.filter("some filter").order_by('title')时,我得到多个标题多次返回的联系人…因为我是按标题排序的,我猜django对使用哪个标题感到困惑?我正在失去我的头脑如何修复它,同时保持按标题排序。

class Title(models.Model):
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
title_name = models.CharField(max_length=40)
class Contact(models.Model):
name_surname = models.CharField(max_length=60)
title = models.ManyToManyField(Title)
...

因为我按标题排序,我猜django对使用哪个标题感到困惑?

实际上您创建了一个LEFT OUTER JOIN,因此对于第二个表中的每个项目,它将检索一条记录。

如果要按最小标题排序,可以使用:

from django.db.models import Min
Contact.objects.filter(…).alias(
min_title=Min('title')
).order_by('min_title')

或django-3.2之前的版本,我们可以注释:

from django.db.models import Min
Contact.objects.filter(…).annotate(
min_title=Min('title')
).order_by('min_title')

您可以使用min_title=Min('title__title_name')按标题的字典顺序排序。

如果您想以一种有效的方式枚举所有Contact的相关title,您可以使用.prefetch_related(…)[Django-doc]在bulk中加载相关项,而不是每Contact:

一个额外的查询
from django.db.models import Min
Contact.objects.filter().alias(
min_title=Min('title')
).order_by('min_title').prefetch_related('title')

最新更新