Django:构建动态查询

时间:2013-08-10 11:32:48

标签: django

我有一个表流派在“名称”栏下有Drana,Thriller,Sci-fi等值。和另一个表电影。 在电影表格中,类型是用于类型表的ManyTOManyField

方案

movie_1 = {D,S, T}
movie_2 = {S,T}
movie_3 = {D}
movie_4 = {D, T}

D:戏剧,S:科幻,T:惊悚

案例1: 假设用户选择D和T(这是复选框选项)

all D movies : movie_1, movie_3, movie_4  ---(a)
all T movies : movie_1, movie_2, movie_4  ---(b)

当用户选择这些选项时: 我想要显示movie_1,movie_2,movie_3,movie_4,它是(a)和(b)的交叉点 对于以上情况,可以像下面这样查询:

        qs_d = Genre.objects.get(name="Drama")
        qs_t = Genre.objects.get(name="Thriller")
        m_d = Movies.objects.filter( Q(gen__id=qs_d.id) | Q(gen__id=qs_t.id)).distinct()
        for movie_name in m_d:
            print movie_name

在上面的查询中,我对“戏剧”和“惊悚”类型(解释)进行了硬编码,但是 我将把电影类型放在像“戏剧”,“喜剧”,“惊悚片”这样的列表中,具体取决于用户选择的选项数量,在这种情况下我如何构建查询?

1 个答案:

答案 0 :(得分:0)

|__or__功能,或者您可以使用operator.or_ function

所以你可以这样做:

from operator import or_
#Uncomment for Python3
#from functools import reduce
...
qs = [Q(gen__id=Genre.objects.get(name=name).id) for name in names]
m_d = Movies.objects.filter(reduce(or_, qs)).distinct()

那应该做你想要的。我对Django查询并不十分熟悉,所以可能有更好的方法。当然,你可以将它与以下内容结合起来:

m_d = Movies.objects.filter(reduce(or_, (Q(gen__id=Genre.objects.get(name=name).id) for name in names))).distinct()