【问题标题】:How to use Q objects in Django如何在 Django 中使用 Q 对象
【发布时间】:2017-05-17 07:01:53
【问题描述】:

我正在尝试了解如何在 Django 中为网站制作简单的搜索表单。经过一些谷歌搜索并且我自己没有几次失败后,我最终在views.py中得到了以下代码,其中'q'是从表单中检索的值:

class BookSearchListView(BookListView):
    def get_queryset(self):
        result=super(BookSearchListView, self).get_queryset()
        query=self.request.GET.get('q')
        if query:
            query_list=query.split()
            result=result.filter(reduce(operator.and_,(Q(title__icontains=q) for q in query_list))) 
        return result

我已经了解它是如何工作的,以及为什么会有 reduce 和 operator.and_(我的意思是,我想我明白了)。但我不明白为什么一个简单的result=result.filter(Q(somedbfield_icontains=q)) 返回和错误(即使输入是一个单词)。我也不明白为什么 reduce 需要获得按位值?

【问题讨论】:

  • 您能否添加您收到的确切错误消息?
  • 当我将其缩减为 result=result.filter(Q(title__icontains=q) for q in query_list) 时,我得到的异常是:“没有足够的值来解包(预期 2,得到 1)”
  • 您不能将可迭代对象传递给过滤器
  • reduce(operator.and_, (a, b, c, ...))a and b and c and ... 相同
  • 所以这里有 and_ :获得单个不可迭代的值?如果是,那么 reduce() 的目的是什么?

标签: python django search


【解决方案1】:

为什么一个简单的 result.filter(Q(somedbfield_icontains=q)) 返回和错误

最简单的变体是result.filter(somedbfield__icontains=q) 那里不需要Q,Q 用于使用逻辑运算符(与、或、非)扩展您的过滤。另外,请注意icontains 之前的双下划线。

为什么reduce需要按位取值?

It dosen't

reduce 用于将任何函数应用于可迭代的参数:

operator.add(1, 2)1 + 2 相同

reduce(operator.add, (1, 2, 3, 4, 5))((((1 + 2) + 3) + 4) + 5) 相同

大致是这样工作的:

def reduce(function, iterable):
    it = iter(iterable)
    value = next(it)

    for element in it:
        value = function(value, element)

    return value

【讨论】:

  • 谢谢。所以这里使用 Q 是因为输入中可能有多个术语,所以它需要使用 OR ?对吗?
  • 没错。 Q 可以与逻辑运算符(和、或、非)一起使用
猜你喜欢
  • 2013-05-30
  • 2015-04-13
  • 2014-07-30
  • 2022-12-29
  • 2021-09-15
  • 2014-03-04
  • 2011-03-14
  • 2013-12-11
相关资源
最近更新 更多