django和Q不适合很多人

时间:2014-06-12 20:30:33

标签: django django-q

以下是模型:

class ModelA:
    title = charfield
    m2m = foreignkey, relatedname='m2ms'

这是有效的:

ModelA.objects.filter(Q(title__icontains='a') & Q(title__icontains='b'))  

因此它返回标题包含字母'a'和'b'的所有记录。

然后同样不适用于许多人:

ModelA.objects.filter(Q(m2ms__id=1) & Q(m2ms__id=2))    

ModelA m2ms列表:

for x in ModelA.objects.all():
    print x.m2ms.all().values_list('id', Flat=True)    

#Output:
1,2,3
1,2
1
1,3,5
4,6,7 
1,8

因此,ModelA.objects.filter(Q(m2ms__id = 1)& Q(m2ms__id = 2))的预期输出应该是具有这些m2m id的记录:[1,2,3],[1,2] 。但它没有发生。为什么?

我不能使用Q(m2ms__id__in = [1,2]),因为它返回相同,即使我做__in = [1,2,3,4,无限数]

在此问题中提到了使用Q而不是过滤器的原因 - django filter on many to many along with Q

1 个答案:

答案 0 :(得分:1)

阅读docs的此部分。

特别是这一段:

  

为了处理这两种情况,Django有一种处理filter()和exclude()调用的一致方法。同时应用单个filter()调用内的所有内容来过滤掉符合所有这些要求的项目。连续的filter()调用进一步限制了对象集,但对于多值关系,它们适用于链接到主模型的任何对象,不一定是那些早先的filter()调用所选择的对象。

我相信如果您执行ModelA.objects.filter(Q(m2ms__id__in=[1, 2]))ModelA.objects.filter(m2ms__id__in=[1, 2]),它会按照您的预期运作。