如何将复杂的 django 查询构建为字符串

Posted

技术标签:

【中文标题】如何将复杂的 django 查询构建为字符串【英文标题】:How to build complex django query as a string 【发布时间】:2014-07-31 06:46:19 【问题描述】:

我正在动态生成具有多个参数的查询字符串。我试图在我的字符串中包含对象名称('nut'、'jam')。查询必须是“OR”查询。我的代码如下,我得到如下所示的错误。 here、here 和 here 的解决方案对我不起作用。

from viewer.models import Model1
from django.db.models import Q
list1 = [
    'nut' : 'peanut', 'jam' : 'blueberry',
    'nut' : 'almond', 'jam' : 'strawberry'
]
query_string = ""
for x in list1:
    if len(query_string) == 0:
        query_string = "Q(nut='%s', jam='%s')" % (x["nut"], x["jam"])
    else:
        query_string = "%s | Q(nut='%s', jam='%s')" % (query_string, x["nut"], x["jam"])
print query_string # correctly prints Q(nut='peanut', jam='blueberry') | Q(nut='almond', jam='strawberry')
query_results = Model1.objects.filter(query_string)

Error: 
#truncated
File "/Library/Python/2.7/site-packages/Django-1.5.4-py2.7.egg/django/db/models/manager.py", line 155, in filter
    return self.get_query_set().filter(*args, **kwargs)
  File "/Library/Python/2.7/site-packages/Django-1.5.4-py2.7.egg/django/db/models/query.py", line 669, in filter
    return self._filter_or_exclude(False, *args, **kwargs)
  File "/Library/Python/2.7/site-packages/Django-1.5.4-py2.7.egg/django/db/models/query.py", line 687, in _filter_or_exclude
    clone.query.add_q(Q(*args, **kwargs))
  File "/Library/Python/2.7/site-packages/Django-1.5.4-py2.7.egg/django/db/models/sql/query.py", line 1271, in add_q
can_reuse=used_aliases, force_having=force_having)
  File "/Library/Python/2.7/site-packages/Django-1.5.4-py2.7.egg/django/db/models/sql/query.py", line 1066, in add_filter
arg, value = filter_expr
ValueError: too many values to unpack

【问题讨论】:

【参考方案1】:

构造一个Q对象并在filter()中使用:

from viewer.models import Model1
from django.db.models import Q

list1 = [
    'nut' : 'peanut', 'jam' : 'blueberry',
    'nut' : 'almond', 'jam' : 'strawberry'
]

q = Q()
for x in list1:
    q.add(Q(**x), Q.OR)

query_results = Model1.objects.filter(q)

或者,您可以使用operator.or_ 加入Q 对象列表:

import operator
from viewer.models import Model1
from django.db.models import Q

list1 = [
    'nut' : 'peanut', 'jam' : 'blueberry',
    'nut' : 'almond', 'jam' : 'strawberry'
]

query_results = Model1.objects.filter(reduce(operator.or_, 
                                             [Q(**x) for x in list1]))

【讨论】:

以上是关于如何将复杂的 django 查询构建为字符串的主要内容,如果未能解决你的问题,请参考以下文章

为了在 Django 中过滤数据,为多列构建动态查询

有没有办法将 Django 模型查询集转换为模板中的 json 或 json 字符串?

在执行查询之前,如何从 Laravel 的查询构建器中获取原始查询字符串?

在 Django 中使用 Q() 动态构建复杂查询 [关闭]

使用 Q-Objects 在 Django 中动态构建复杂查询

Json.Net 将复杂的查询字符串转换为 JsonString