繁体   English   中英

Django Q 过滤器 - 要解压的值太多

[英]Django Q Filter - Too many Values to unpack

我想根据 url 查询参数动态创建一些过滤条件。 为此,我创建了一个嵌套的 Django Q-Object,如下所示:

query = <Q: (AND: (OR: region=30, region=39), name__endswith=Hannover, zip_code=30165)>

现在我想将这个 Q object 传递给 Model-Filter

Eort.objects.filter(query)

因此我得到一个 ValueError: too many values to unpack (expected 2)

Traceback (most recent call last):
  File "C:\Users\felix\Documents\WZO\myenv\lib\site-packages\django\core\handlers\exception.py", line 47, in inner
    response = get_response(request)
  File "C:\Users\felix\Documents\WZO\myenv\lib\site-packages\django\core\handlers\base.py", line 181, in _get_response     
    response = wrapped_callback(request, *callback_args, **callback_kwargs)
  File "C:\Users\felix\Documents\WZO\myenv\lib\site-packages\django\views\decorators\csrf.py", line 54, in wrapped_view    
    return view_func(*args, **kwargs)
  File "C:\Users\felix\Documents\WZO\myenv\lib\site-packages\django\views\generic\base.py", line 70, in view
    return self.dispatch(request, *args, **kwargs)
  File "C:\Users\felix\Documents\WZO\myenv\lib\site-packages\rest_framework\views.py", line 509, in dispatch
    response = self.handle_exception(exc)
  File "C:\Users\felix\Documents\WZO\myenv\lib\site-packages\rest_framework\views.py", line 469, in handle_exception       
    self.raise_uncaught_exception(exc)
  File "C:\Users\felix\Documents\WZO\myenv\lib\site-packages\rest_framework\views.py", line 480, in raise_uncaught_exception
    raise exc
  File "C:\Users\felix\Documents\WZO\myenv\lib\site-packages\rest_framework\views.py", line 506, in dispatch
    response = handler(request, *args, **kwargs)
  File "C:\Users\felix\Documents\WZO\WZO\WZO_App\views.py", line 47, in get
    log.debug(Eort.objects.filter(eq))
  File "C:\Users\felix\Documents\WZO\myenv\lib\site-packages\django\db\models\manager.py", line 85, in manager_method      
    return getattr(self.get_queryset(), name)(*args, **kwargs)
  File "C:\Users\felix\Documents\WZO\myenv\lib\site-packages\django\db\models\query.py", line 942, in filter
    return self._filter_or_exclude(False, *args, **kwargs)
  File "C:\Users\felix\Documents\WZO\myenv\lib\site-packages\django\db\models\query.py", line 962, in _filter_or_exclude   
    clone._filter_or_exclude_inplace(negate, *args, **kwargs)
  File "C:\Users\felix\Documents\WZO\myenv\lib\site-packages\django\db\models\query.py", line 969, in _filter_or_exclude_inplace
    self._query.add_q(Q(*args, **kwargs))
  File "C:\Users\felix\Documents\WZO\myenv\lib\site-packages\django\db\models\sql\query.py", line 1358, in add_q
    clause, _ = self._add_q(q_object, self.used_aliases)
  File "C:\Users\felix\Documents\WZO\myenv\lib\site-packages\django\db\models\sql\query.py", line 1380, in _add_q
    split_subq=split_subq, check_filterable=check_filterable,
  File "C:\Users\felix\Documents\WZO\myenv\lib\site-packages\django\db\models\sql\query.py", line 1244, in build_filter    
    check_filterable=check_filterable,
  File "C:\Users\felix\Documents\WZO\myenv\lib\site-packages\django\db\models\sql\query.py", line 1380, in _add_q
    split_subq=split_subq, check_filterable=check_filterable,
  File "C:\Users\felix\Documents\WZO\myenv\lib\site-packages\django\db\models\sql\query.py", line 1244, in build_filter    
    check_filterable=check_filterable,
  File "C:\Users\felix\Documents\WZO\myenv\lib\site-packages\django\db\models\sql\query.py", line 1380, in _add_q
    split_subq=split_subq, check_filterable=check_filterable,
  File "C:\Users\felix\Documents\WZO\myenv\lib\site-packages\django\db\models\sql\query.py", line 1255, in build_filter    
    arg, value = filter_expr

有谁知道如何解决这个问题?

这就是我创建 Q-Object 的方式:

def or_operator(self, key, qlist):
        if qlist:
            result = Q()
            result.connector = Q.OR
            for i in qlist:
                if i == '':
                    continue
                if i[0] == '%' and i[-1] == '%':
                    result.add(Q('{0}__{1}={2}'.format(key, 'contains', i[1:-1])), Q.OR)
                elif i[0] == '%' and not i[-1] == '%':
                    result.add(Q('{0}__{1}={2}'.format(key, 'startswith', i[1:])), Q.OR)
                elif not i[0] == '%' and i[-1] == '%':
                    result.add(Q('{0}__{1}={2}'.format(key, 'endswith', i[:-1])), Q.OR)
                else:
                    result.add(Q('{0}={1}'.format(key, i)), Q.OR)
            return result 

query = Q()
query.connector = Q.AND
for key in params:
    if key in ['lat', 'lng', 'name', 'street', 'zip_code', 'city', 'region']:
        val = params.get(key, None).split(',')
        query.add(self.or_operator(key, val),Q.AND)

您不应该使用={2} A Q object不是foo=bar形式的字符串,它本质上是一个 2 元组,第一个元素是一个字符串,它是字段和可选的一些查找的“键”,第二个元素是一个值,但该值可以是字符串、 datetime时间 object 等。因此,您可以使用以下命令构造Q object:

if i[0] == '%' and i[-1] == '%':
    result.add(Q((f'{key}__contains', i[1:-1])), Q.OR)
elif i[0] == '%' and not i[-1] == '%':
    result.add(Q((f'{key}__startswith', i[1:])), Q.OR)
elif not i[0] == '%' and i[-1] == '%':
    result.add(Q((f'{key}__endswith', i[:-1])), Q.OR)
else:
    result.add(Q((key, i)), Q.OR)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM