[英]Django .exclude() returns empty queryset
I have a problem with .exclude()
when making a QuerySet.我在制作 QuerySet 时遇到
.exclude()
问题。
My models involved are:我涉及的模型是:
Profession职业
class Profession(models.Model):
profession_name = models.CharField(max_length=20)
equipment = models.ManyToManyField(Equipment, blank=True)
ability = models.ManyToManyField(Ability, blank=True)
skill = models.ManyToManyField(Skill, blank=True)
skill_advanced = models.ManyToManyField(SkillAdvanced, blank=True)
Ability能力
class Ability(models.Model):
ability_name = models.CharField(max_length=35)
When I create QuerySet with:当我创建 QuerySet 时:
self.prof_abilities = Profession.objects.filter(profession_name="Acolyte").values('ability')
I get:我得到:
<QuerySet [{'ability': 2}, {'ability': 69}, {'ability': 81}, {'ability': 86}, {'ability': 23}]>
But I would like to exclude some values, so I use this instead:但我想排除一些值,所以我改用它:
self.prof_abilities = Profession.objects.filter(profession_name="Acolyte").exclude(ability__in=[2, 23, 81, 86]).values('ability')
But the outcome is an empty QuerySet: <QuerySet []>
.但结果是一个空的 QuerySet:
<QuerySet []>
。
I've tried various tweeks like .exclude(ability__id__in=[2, 23, 81, 86])
or .exclude(ability__ability_name__in=['Foo name', 'Bar name']
but with no success.我尝试了各种 tweeks,例如
.exclude(ability__id__in=[2, 23, 81, 86])
或.exclude(ability__ability_name__in=['Foo name', 'Bar name']
但没有成功。
I'm new to Django so if this is something obvious, I would also appreciate some pointers where to read more on my mistake.我是 Django 的新手,所以如果这是显而易见的事情,我也很感激一些指示,可以在哪里阅读更多关于我的错误的信息。
Your queryset is for the Profession
model, hence when you write queryset.exclude(ability__in=<list_of_abilities>)
you get a queryset where you exclude Profession
(Not Ability
) instances where the ability is in the given list, ie if any of the Ability
related to a Profession
is in that list that profession would be excluded.您的查询集适用于
Profession
model,因此当您编写queryset.exclude(ability__in=<list_of_abilities>)
时,您会得到一个查询集,您可以在其中排除能力在给定列表中的Profession
(不是Ability
)实例,即如果任何Ability
与Profession
相关的信息在该列表中,该专业将被排除在外。 Instead if you get the Profession
object first and then filter on the relation manager you will get your expected result:相反,如果您首先获得
Profession
object,然后过滤关系经理,您将获得预期的结果:
queryset = Profession.objects.filter(profession_name="Acolyte")
for profession in queryset:
print(profession.ability.exclude(id__in=[2, 23, 81, 86]))
Since Ability
is a manyToManyField
, the each profession.ability
object will have django.db.models.fields.related.ManyRelatedManager
and not the direct list of ability objects.由于
Ability
是一个manyToManyField
,每个profession.ability
object 将具有django.db.models.fields.related.ManyRelatedManager
而不是能力对象的直接列表。 So if you want to get All professions that excludes ability with specific ids you can try changing your query from因此,如果您想获得排除具有特定 ID 能力的所有职业,您可以尝试更改您的查询
self.prof_abilities = Profession.objects.filter(profession_name="Acolyte").exclude(ability__in=[2, 23, 81, 86]).values('ability')
to到
self.prof_abilities = Profession.objects.filter(profession_name="Acolyte").exclude(ability__in=Ability.objects.filter(id__in=[2, 23, 81, 86])).values('ability')
filter
and exclude
behaves differently with respect to multi-valued relationships
. filter
和exclude
对于multi-valued relationships
行为不同。
Although didn't find a link for valid explanation for my answer, here is a link from documentation discussing something related虽然没有找到对我的答案进行有效解释的链接,但这里有一个来自讨论相关内容的文档的链接
Scroll down to note
part of this section link: https://docs.djangoproject.com/en/3.2/topics/db/queries/#spanning-multi-valued-relationships向下滚动以
note
本节链接的一部分: https://docs.djangoproject.com/en/3.2/topics/db/queries/#spanning-multi-valued-relationships
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.