Django:扩展查询集或从exclude方法中排除

时间:2015-06-02 18:50:18

标签: python django

我有一个Django应用程序,我需要组合两个QuerySet,并且只针对某些项目忽略exclude()过滤器。

以下是模型和查询的示例。

class MyModel(models.Model):
    name = models.CharField(max_length=20)
    var1 = models.IntegerField()
    var2 = models.BooleanField()
    var3 = models.BooleanField()
    var4 = models.IntegerField()
    var5 = models.IntegerField()

qs1 = MyModel.objects.filter(var1__lte=10,var2=True).exclude(Q(var4=10) | Q(var5=20))

must_include_list = ['name1','name2','name3']

qs2 = MyModel.objects.filter(name__in=must_include_list)

我需要一个单独的查询集来执行过滤并从qs1中排除,但也包括来自qs2的行,无论它们是否与qs1过滤器匹配并排除。

我试过这样做:

qs1 = MyModel.objects.filter(Q(var1__lte=10,var2=True) | Q(name__in=must_include_list)).exclude(Q(var4=10| | Q(var5=20))

但它仍然将排除应用于must_include_list,所以我想念一些必需的条目。

有没有办法告诉exclude()不要排除must_include_list中的项目,还是有办法将两者结合起来,因为查询集没有extend()方法?

我的解决方案基于bakkal的建议。

INCLUDE = Q(var1__lte=10,var2=True)
EXCLUDE = Q(var4=10) | Q(var5=20)
MUST_INCLUDE = Q(name__in=must_include_list)
FILTER = (INCLUDE & ~EXCLUDE) | MUST_INCLUDE
MyModel.objects.filter(FILTER).distinct()

1 个答案:

答案 0 :(得分:1)

让我们改写

MyModel.objects.filter(var1__lte=10,var2=True).exclude(Q(var4=10) | Q(var5=20))

作为

X = Q(var1__lte=10, var2=True) & ~(Q(var4=10) | Q(var5=20))
MyModel.objects.filter(X)

另一个查询只是

Y = Q(name__in=must_include_list)

现在你想要的是X或Y所以

MyModel.objects.filter(X | Y)

提示:如果您将X和Y重命名为有意义的名称,那么您的代码将变得可读且干净,并且比阅读嵌套的过滤器/排除和逻辑运算符更加神秘