我在制作.exclude()时遇到了QuerySet的问题。
我的模特是:
职业
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)能力
class Ability(models.Model):
ability_name = models.CharField(max_length=35)当我创建QuerySet时:
self.prof_abilities = Profession.objects.filter(profession_name="Acolyte").values('ability')我得到:
<QuerySet [{'ability': 2}, {'ability': 69}, {'ability': 81}, {'ability': 86}, {'ability': 23}]>但是我想排除一些值,所以我使用以下方法:
self.prof_abilities = Profession.objects.filter(profession_name="Acolyte").exclude(ability__in=[2, 23, 81, 86]).values('ability')但结果是一个空的QuerySet:<QuerySet []>。
我试过几个星期,比如.exclude(ability__id__in=[2, 23, 81, 86])或.exclude(ability__ability_name__in=['Foo name', 'Bar name'],但都没有成功。
我是Django的新手,所以如果这是很明显的事情,我也希望能有更多关于我的错误的建议。
发布于 2021-10-11 09:57:06
您的查询集是针对Profession模型的,因此,当您编写queryset.exclude(ability__in=<list_of_abilities>)时,您会得到一个查询集,其中排除了给定列表中有能力的Profession (而不是Ability)实例,也就是说,如果与Profession相关的任何Ability都在该列表中,则该职业将被排除在外。相反,如果您首先获得Profession对象,然后对关系管理器进行筛选,您将得到预期的结果:
queryset = Profession.objects.filter(profession_name="Acolyte")
for profession in queryset:
print(profession.ability.exclude(id__in=[2, 23, 81, 86]))发布于 2021-10-11 10:37:15
因为Ability是一个manyToManyField,所以每个profession.ability对象都有django.db.models.fields.related.ManyRelatedManager,而不是能力对象的直接列表。因此,如果您想获得所有排除具有特定ids的能力的职业,可以尝试将查询更改为
self.prof_abilities = Profession.objects.filter(profession_name="Acolyte").exclude(ability__in=[2, 23, 81, 86]).values('ability')至
self.prof_abilities = Profession.objects.filter(profession_name="Acolyte").exclude(ability__in=Ability.objects.filter(id__in=[2, 23, 81, 86])).values('ability')filter和exclude对于multi-valued relationships的行为不同。
虽然没有找到有效解释我的答案的链接,但这里有一个链接,来自讨论相关内容的文档
向下滚动到本节链接的note部分:https://docs.djangoproject.com/en/3.2/topics/db/queries/#spanning-multi-valued-relationships
https://stackoverflow.com/questions/69524122
复制相似问题