简体   繁体   English

Django.exclude() 返回空查询集

[英]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 )实例,即如果任何AbilityProfession相关的信息在该列表中,该专业将被排除在外。 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 . filterexclude对于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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM