使用 __in=[somelist] 过滤模型的 ManyToMany 字段会产生零结果,而它应该产生多个

Posted

技术标签:

【中文标题】使用 __in=[somelist] 过滤模型的 ManyToMany 字段会产生零结果,而它应该产生多个【英文标题】:Filtering a model's ManyToMany field with __in=[somelist] produces zero results when it should produce several 【发布时间】:2017-12-26 15:33:06 【问题描述】:

我还没有在网上找到解决方案——我不可能是第一个尝试这个的人。

这是我的模型结构:

class TopModel(models.Model):
    type = models.CharField()

class MiddleModel(models.Model):
    parent = models.ForeignKey(TopModel)

class LowerModel(model.Model):
    middleParent = models.ForeignKey(MiddleModel)
    topParent = models.ForeignKey(TopModel, related_name="ref_to_top_parent")
    topmodel_refs = models.ManyToMany(TopModel, related_name="ref_to_other_tops")

我需要通过一些奇怪的查询进行过滤。我使用 MiddleModel 过滤 Top Model 两次——你会看到的。

所以我正在制作 2 个查询集:

currentMidMod = MiddleModel.objects.get(pk=1)
firstQuerySet = currentMidMod.topmodel_set.all()

secondMidMod = MiddleModel.objects.get(pk=2)
secondQuerySet = secondMidMod.topmodel_set.all()

然后我过滤第一个:

firstQuerySet = firstQuerySet.filter(type__contains="somevalue")

然后我过滤第二个:

secondQuerySet = secondQuerySet.filter(type__contains="test") #produces a count() of 10
#Grab a valueset of the pks
compareList = list(secondQuerySet.values_list('pk', flat=True))

那么问题就出现在这里:

newQuerySet = firstQuerySet.filter(ref_to_top_parent__topmodel_refs__in=compareList)

newQuerySet.count() #equals 0 when I know it should equal 5

因此,我试图通过将其与我创建的值列表中的 pk 值列表进行比较,通过这些 LowerModels ManyToMany 键列表返回 TopModels 来过滤我的所有 LowerModel 反向外键的第一个查询集

即使我可以手动查看 phpAdmin 并自己找到匹配项,它也永远找不到匹配的“pks”

我快死了。请帮忙!

编辑:当尝试查询单个 PK 而不是列表时 - 它可以正常工作,例如

newQuerySet = firstQuerySet.filter(ref_to_top_parent__topmodel_refs__pk=74956)

当尝试将该 ManyToMany 字段与值的 list() 进行比较时(包括“74956”),它没有找到任何匹配项——它至少应该在我想象的 values_list 中找到“74956”。

【问题讨论】:

firstQuerySet 中的count() 是什么? 这并不重要——实际上它大约是 112,000,其中第二个查询集约为 500 问题是 LowerModel 与 TopModels 具有 ManyToMany 关系——我需要混淆地过滤掉 TopModels通过将反向查找的 ManyToMany 字段与值列表进行比较。我不确定这是否可能。 好吧,如果它是 0 就很重要了。 touché 哈哈!它是否为零很重要 抱歉,我不确定是什么问题。您是否检查以确保将条目添加到 ManyToMany 字段的中间表中? 【参考方案1】:

正如原始问题的 cmets 中所讨论的,未在中间表中为多对多关系创建条目。我只想要网点! :)

【讨论】:

以上是关于使用 __in=[somelist] 过滤模型的 ManyToMany 字段会产生零结果,而它应该产生多个的主要内容,如果未能解决你的问题,请参考以下文章

如何使用时区感知日期过滤模型?

Not in 子句不使用开放查询过滤 SQL Server

如何使用或使用 Django 的模型过滤系统?

如何在火花的过滤条件中使用NOT IN子句

仅使用具有“in”子句中所有值的列加入查询

07_LFM--梯度下降法--实现基于模型的协同过滤