构造后可以修改Django Q()对象吗?

5 投票
3 回答
592 浏览
提问于 2025-04-19 14:37

可以在创建后修改Django的Q()对象吗?我这样创建了一个Q()对象:

q = Q(foo=1)

我想知道,之后能不能把q改成和我刚开始构造的那样:

q2 = Q(foo=1, bar=2)

在我查找的Django文档中,没有找到相关的说明。

我在寻找类似于:

Q.append_clause(bar=2)

3 个回答

0

这里的回答有点旧,感觉不太满意。所以我来给个新的答案。

这是如何进行深拷贝的方法:

def deep_copy(q: Q) -> Q:
    new_q = Q()
    # Go through the children of a query: if it's another
    # query it will run this function recursively
    for sub_q in q.children:
        # Make sure you copy the connector in 
        # case of complicated queries
        new_q.connector = q.connector
        if isinstance(sub_q, Q):
            # This will run recursively on sub queries
            sub_q = get_employee_q(sub_q)
        else:
            pass # Do your modification here
        new_q.children.append(sub_q)
    return new_q

在else条件下,你的内容(比如name='nathan')就是在这里定义的。如果你想的话,可以修改或者删除它,这样查询应该就能正常工作了。

5

你可以把 Q 对象加在一起,使用它们的 add 方法。比如:

>>> q = Q(sender=x)
>>> q.add(Q(receiver=y), Q.AND)

传给 add 的第二个参数是连接符,它也可以是 Q.OR

编辑:我的回答其实只是另一种实现 Perrin Harkins 提出的建议。不过,关于你提到的一个问题,就是根据查询的构造方式,filter 的行为可能不同,你不需要担心这一点,如果你把 Q 对象连接起来。我的例子等同于 filter(sender=x, receiver=y),而不是 filter(sender=x).filter(receiver=y)。因为根据我快速测试的结果,Q 对象会立即对这些条件进行 AND 操作,并且没有 filter 在多值关系中的特殊行为。

无论如何,查看 SQL 语句,确保它在你的具体查询中确实是一样的,这总是个好主意。

6

你可以再创建一个 Q() 对象,然后把它们用“与”运算符连接起来:q2 = q & Q(bar=2)

撰写回答