Django 从模型中过滤:Model.objects.filter(Q())

Posted

技术标签:

【中文标题】Django 从模型中过滤:Model.objects.filter(Q())【英文标题】:Django filtering from models: Model.objects.filter(Q()) 【发布时间】:2016-03-10 23:14:23 【问题描述】:

我需要使用 django ORM 在数据库中搜索一些数据,这应该是按所有列搜索。问题是在我将函数作为参数输入之前,我不知道要搜索什么。

这是源代码:

search = request.GET.get('search_value')
#row_to_search is turple i get to function
#it could be different at every searching
#it looks like here:
rows_to_search = ('name', 'age', 'salary')

我需要在我的数据库中搜索这些行,如下所示:

query = Mymodel.objects.filter(Q(name__iregex=search) |      \
                               Q(age__iregex=search)  |      \
                               Q(salary__iregex=search))

如果要搜索更多行,我该如何编写代码?

我尝试过这样的事情,但它似乎根本不起作用:

Q_filter = map(lambda q: 'Q('+q+')', map(lambda s: s+'__regex='+search, rows_to_search))
searchline = '|'.join(Q_filter)

我不能调用model.objects.filter(searchline),因为它是一个字符串。 有可能在这里做点什么,还是架构错了?我应该制作自定义模型管理器吗?

【问题讨论】:

【参考方案1】:

这是一种明确的方法:

>>> Q_filter = Q()
>>> for value in rows_to_search:
...     Q_filter |= Q(**"__iregex".format(value): search)

这是使用reduce() 的单行代码:

>>> Q_filter = reduce(lambda x, y: x | Q(**"__iregex".format(y): search), rows_to_search, Q())

另一个使用 operator.or_ 和列表推导的单行:

>>> Q_filter = reduce(operator.or_, [Q(**"__iregex".format(key): search) for key in rows_to_search])

那么就可以这样调用查询了:

MyModel.objects.filter(Q_filter)

【讨论】:

非常感谢 ozgul 它对我来说非常有用!

以上是关于Django 从模型中过滤:Model.objects.filter(Q())的主要内容,如果未能解决你的问题,请参考以下文章

Django:使用嵌套模型从许多关系查询中进行复杂排序和过滤

Django 从模型中过滤:Model.objects.filter(Q())

Django中模型

在 Django 中使用继承过滤模型

django基础知识之模型查询:

使用 Ajax 按钮过滤 Django 模型