Django:如何使用Q对象的自定义查询集保持DRY?

时间:2017-11-13 14:59:08

标签: python django django-models

在自定义查询集示例中,displayable方法使用permanentscheduled方法的组合。它有效,但正如你所看到的,我正在重复自己:

class ArticlesByCategoryQuerySet(models.QuerySet):
    def permanent(self):
        return self.filter(is_permanent=True)

    def scheduled(self, service):
        return self.filter(scheduled_services__in=[service])

    def displayable(self, service):
        complex_query = Q(is_permanent=True) | Q(scheduled_services__in=[service])
        return self.filter(complex_query)

使用Q()并保持DRY的正确语法是什么?我没有在Django文档中找到这样的例子。 我尝试了类似的东西,但它提出了ValueError: too many values to unpack (expected 2)

def displayable(self, service):
    complex_query = Q(self.permanent()) | Q(self.scheduled(service))
    return self.filter(complex_query)

感谢您的帮助。

3 个答案:

答案 0 :(得分:1)

您可以在Django 1.11中使用查询集New的union() method,它使用SQL的UNION运算符来组合两个或更多QuerySet的结果。

def displayable(self, service):
    qs1 = self.permanent()
    qs2 = self.scheduled(service)
    return qs1.union(qs2)

UNION运算符默认情况下仅选择不同的值。要允许重复值,请使用all=True参数。

<强>更新

两者都用于合并/组合查询集,union()是Django 1.11中的新功能

主要区别是* union( other_qs,all = False)返回第一个QuerySet类型的模型实例,即使参数是其他模型的QuerySets。

QuerySets的union运算符是|管道符号,仅适用于来自同一模型的查询集,并且在切片之前。

答案 1 :(得分:1)

查询集也可以与按位or结合使用:

class ArticlesByCategoryQuerySet(models.QuerySet):
    def permanent(self):
        return self.filter(is_permanent=True)

    def scheduled(self, service):
        return self.filter(scheduled_services__in=[service])

    def displayable(self, service):
        return self.permanent() | self.scheduled(service)

答案 2 :(得分:0)

您可以将Q对象存储在如下方法中:

-s