仅在链接到实例的第一个外键上进行查询集

Queryset only on the first foreign key linked to the instance

假设我有这些模型:

class Person(models.Model):
    name = models.CharField(max_length=50, blank=True, null=True, verbose_name=_('name'))


class Keyword(models.Model):
    value = models.CharField(max_length=50, blank=True, null=True, verbose_name=_('name'))
    person = models.ForeignKey('Keyword', on_delete=models.CASCADE)

我想查询 Person 模型,我们只过滤与那个人相关的第一个关键字。

关键字列表总是有序的。

例如:

李四有 3 个关键字(编程、旅行、家庭)

我想做这样的事情(如果可能的话)

Person.objects.filter(keyword_"first"="Programming") 

可以用.alias(…) [Django-doc] with a Subquery expression [Django-doc]注释,然后过滤:

from django.db.models import OuterRef, Subquery

class Person.objects.alias(
    first_keyword=Subquery(
        Keyword.objects.filter(
            person=OuterRef('pk')
        ).values('value')[:1]
    )
).filter(
    first_keyword='Programming'
)

但是模型默认是无序的:这意味着每次不同的关键字可以是第一个。只有在子查询中有一个列和一个ordering option [Django-doc], or an .order_by(…) clause [Django-doc],才能保证某一项是第一个关键字。

您可以使用字段 only_first 使过滤可选,如果 True 则过滤第一个项目,如果 False:

则过滤所有项目
from django.db.models import OuterRef, Q, Subquery

class Person.objects.alias(
    first_keyword=Subquery(
        Keyword.objects.filter(
            person=OuterRef('pk')
        ).values('value')[:1]
    )
).filter(
    Q(first_keyword='Programming') |
    Q(only_first=False, keyword__value='Programming')
)