如何使用Django.db.models Q模块查询多行用户输入文本数据
Posted
技术标签:
【中文标题】如何使用Django.db.models Q模块查询多行用户输入文本数据【英文标题】:How can I use Django.db.models Q module to query multiple lines of user input text data 【发布时间】:2018-11-27 13:47:25 【问题描述】:我将如何使用 django.db.models Q 模块使用<textarea>
html 输入字段从数据列表中查询多行输入?我可以使用普通的 html <input>
字段很好地查询单个对象。我尝试使用与输入字段相同的代码,除了在请求输入数据时,我尝试像这样拆分行:
def search_list(request):
template = 'search_result.html'
query = request.GET.get('q').split('\n')
for each in query:
if each:
results = Product.objects.filter(Q(name__icontains=each))
这当然行不通。我查询一行数据的代码(有效)是这样的:
def search(request):
template = 'search_result.html'
query = request.GET.get('q')
if query:
results = Product.objects.filter(Q(name__icontains=query))
我基本上只是想在我的数据库中搜索用户输入到列表中的数据列表,并通过一个查询返回所有这些结果。您的帮助将不胜感激。谢谢。
【问题讨论】:
应该是 and 还是 or 逻辑:任何元素是否足够,或者文本是否应该包含 all ? 如果没有给出这样的查询应该怎么办? @WillemVanOnsem 应该是“或”逻辑。它应该匹配我数据库中每行文本的名称/短语中存在的任何单词并返回结果。如果没有给出查询,或者给出了不正确的查询,我将在页面上显示与每一行匹配的所有查询,并用某种类型的错误消息代替无效查询。如果我没有正确回答您的问题,请告诉我。 【参考方案1】:根据您的 cmets,您希望为给定的 q
字符串实现 OR-逻辑。
我们可以通过reduce
来创建这样的Q
对象——创建一个Q
对象列表,每个对象都指定一个Q(name__icontains=...)
约束。我们用“逻辑或”(Python |
中的管道)来减少它,例如:
from django.db.models import Q
from functools import reduce
from operator import or_
def search_list(request):
template = 'search_result.html'
results = Product.objects.all()
error = None
query = request.GET.get('q')
if query:
query = query.split('\n')
else:
error = 'No query specified'
if query:
results = results.filter(
reduce(or_, (Q(name__icontains=itm.strip()) for itm in query))
)
elif not error:
error = 'Empty query'
some_context =
'results' : results,
'error': error
return render(request, 'app/some_template.html', some_context)
因此,我们首先检查q
是否存在并且不是空字符串。如果是这种情况,则错误为'No query specified'
。如果有查询,我们拆分该查询,接下来我们检查查询中是否至少有一个元素。如果不是,我们的错误是 'Empty query'
(请注意,普通的 .split('\n')
可能不会发生这种情况,但也许你对列表进行后处理,例如删除空元素)。
如果query
中有元素,我们执行reduce(..)
函数,从而过滤Product
s。
最后,我们返回一个带有some_template.html
的render(..)
ed 响应,以及一个包含error
和result
的上下文。
【讨论】:
太棒了。这看起来正是我正在寻找的。我会尽快尝试并报告。非常感谢。 我遇到了一些麻烦。该代码适用于一个对象,但当我输入两行数据时不返回任何内容。我认为当我收到查询时,它返回 1 个对象,而不是按行拆分它们。例如,我收到一个关于 redgreen 的查询,而不是一个针对红色和一个针对绿色的查询。我是否使用了不正确的 html 字段?当我使用<textfield>
查询 1 个对象时它有效,但当我添加新行时它为零。该代码似乎应该可以正常工作。
你能否为query
添加一个print(query)
语句(拆分后,所以在第二个if
之前),并分享值是什么。
控制台没有打印任何内容。 Get请求正在通过,如下:"GET /results/?q=apple%0D%0Apink HTTP/1.1" 200 14350
@juju:啊,那是回车。我们.strip(..)
所有元素是什么?以上是关于如何使用Django.db.models Q模块查询多行用户输入文本数据的主要内容,如果未能解决你的问题,请参考以下文章
AttributeError:模块'django.db.models'没有属性'DataField'[关闭]