【问题标题】:Django: constructing dyanamic queryDjango:构建动态查询
【发布时间】:2013-08-12 06:08:57
【问题描述】:

我有一个表流派,在“名称”列下有 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

在上面的查询中,我已经硬编码了“戏剧”和“惊悚片”类型(用于解释),但是
根据用户选择的选项数量,我将在 {"Drama"、"Comedy"、"Thriller"} 等列表中获取电影类型,在这种情况下,我该如何构建查询?

【问题讨论】:

    标签: django


    【解决方案1】:

    |__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()
    

    【讨论】:

    • 未定义变量或?
    • 大概你有一些 names 可迭代的,例如names = ["Drama", "Thriller", "Comedy"]
    • 的语法是正确的,不应该像 or_(a,b)。我如何导入 or_?
    • 见第一行:from operator import or_。如果语法让您感到困惑,您可能需要查看 docs 的 reduce。你试过这个代码吗?它会给你一个错误吗?如果是这样,(完整)错误是什么?
    • 修复 or_ import 后,它给出了电影查询中的错误:|: 'Genre' 和 'Genre' 的不支持的操作数类型
    猜你喜欢
    • 2019-06-24
    • 2012-11-23
    • 2020-04-22
    • 2021-07-13
    • 2019-04-08
    • 2012-12-21
    • 2018-12-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多