我有一个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()
答案 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重命名为有意义的名称,那么您的代码将变得可读且干净,并且比阅读嵌套的过滤器/排除和逻辑运算符更加神秘