Django,如何使用过滤器检查参数中是否包含字符串字段

RVC*_*RVC 5 python django

说,我有一个带有文本字段的模型:

class SomeModel
    keyword=models.CharField(null=True, max_length=255)
Run Code Online (Sandbox Code Playgroud)

现在,我知道如何检查参数字符串(让我们调用变量“querystring”是否包含在 field 关键字中:

results = SomeModel.objects.filter(keyword_icontains=querystring).all()
Run Code Online (Sandbox Code Playgroud)

我在django 文档中找到的

问题,如何过滤字段值包含在查询字符串变量中的对象?

抱歉,如果我的问题令人困惑......也许一个例子会澄清......在django文档中,如果我的关键字字段包含,例如,'python-django',那么,对于包含'django'的查询字符串,我可以提取包含该字段的对象

results=SomeModel.objects.filter(keyword_icontains=querystring).all()
or results=SomeModel.objets.filter(keyword_icontains='django').all()
Run Code Online (Sandbox Code Playgroud)

但是说,我想提取关键字字段包含在查询字符串中的所有行/对象?例如,如果查询字符串包含“在 django 中,我如何创建过滤器”?然后我希望结果包含关键字字段具有值“django”、“filter”等的所有对象...

小智 5

您必须将输入拆分为单词(取决于您对“单词”的定义),然后迭代它们,连接各种结果查询集(其中大部分可能为空)。

要拆分,您可以使用正则表达式,捕获所有字母和撇号(但如果有人将其用作输入而不是标准 ASCII 撇号,则会错过智能引号):

words = re.split(r"[^A-Za-z']+", querystring)
Run Code Online (Sandbox Code Playgroud)

然后循环和过滤:

query = Q()  # empty Q object
for word in words:
    # 'or' the queries together
    query |= Q(keyword_icontains=word)
results = SomeModel.objects.filter(query).all()
Run Code Online (Sandbox Code Playgroud)

上面的代码未经测试,我从这个答案中得到了“或”查询和空 Q() 的想法。

根据您的下一步,在每个循环步骤中直接评估查询,附加到results列表中,可能对您更好(使用例如itertools.chain,根据此答案)。


小智 5

这是一个解决方案,它将选择SomeModelkeyword是查询字符串的任何子字符串的行,而不仅仅是完整的单词:

SomeModel.objects\
    .annotate(querystring=Value(querystring, output_field=CharField()))\
    .filter(querystring__icontains=F('keyword'))
Run Code Online (Sandbox Code Playgroud)

有关annotateValue 表达式F 表达式的信息,请参阅文档