如何拆分用户在 Django 应用程序的输入字段中插入的单词
how to split words that user inserts in input field in Django app
我有一个搜索栏,正在搜索 2 个模型列标题,body,short_description。我am.usingMySQL数据库。现在,我正在使用 Q 查询,但我想 'improve'.
有一些搜索限制
其中之一是 Q 查找仅基于与字段中完全相同的短语结果查找结果,例如,我有标题 why python is so amazing?
,我必须写 why
或 python
或 python is
以获得结果。我想要的是扩展搜索栏以按以下方式工作:
用户在搜索栏中插入一个问题:python language
并且搜索查找拆分每个单词并 returning 所有 object 包含 python
或 language
。最后,无论用户输入 python language
还是 amazing python
.
,结果都是 return object 和 why python is so amazing?
我在下面发布我当前的代码:
views.py
def search_items(request):
query = request.GET.get('q')
article_list= Article.objects.filter(title__icontains=query)
qa_list = QA.objects.filter(title__icontains=query)
if query is not None:
lookups = Q(title__icontains=query) | Q(short_description__icontains=query) | Q(body__icontains=query)
article_list= Article.objects.filter(lookups, status=1).distinct()
qa_list = QA.objects.filter(lookups, status=1).distinct()
context = {
'query_name': query,
'article_list': article_list,
'qa_list': qa_list,
}
return render(request, 'search/search_items.html', context)
我检查了这个 solution and this one 但结果并不令人满意,因为当我输入 python language
来查找标题为 why python is so amazing
的 object 时,我没有得到任何结果.
问题
对于如何获得 objects 的结果以及基于用户在输入字段中输入的单词的所有 objects 的列表,我将不胜感激。
我 运行 遇到了同样的问题,并通过在我的模型上方的 models.py 中添加自定义搜索管理器解决了这个问题。管理器有两种方法,一种用于单词搜索,另一种用于multi-word。使用下面的 .split()
将查询字符串拆分为单词列表(参见视图)。
models.py
class MyModelSearchManager(models.QuerySet):
def search(self, query=None):
qs = self
if query is not None:
or_lookup = (Q(some_field__icontains=query))
qs = qs.filter(or_lookup).distinct()
return qs
def search_and(self, query=None):
qs = self
if query is not None:
or_lookup = reduce(lambda x, y: x & y, [Q(some_field__icontains=word) for word in query])
qs = qs.filter(or_lookup).distinct()
return qs
class MyModelManager(models.Manager):
def get_queryset(self):
return MyModelSearchManager(self.model, using=self._db)
def search(self, query=None):
return self.get_queryset().search(query=query)
def search_and(self, query=None):
return self.get_queryset().search_and(query=query)
当然,在您的模型字段下方声明自定义管理器:
objects = MyModelManager()
然后,在您看来,拆分搜索字符串并区分单词搜索和 multi-word 搜索:
class SearchView(ListView):
template_name = 'my_app_templates/search_results.html'
count = 0
def get_context_data(self, *args, **kwargs):
context = super().get_context_data(*args, **kwargs)
context['count'] = self.count or 0
context['query'] = self.request.GET.get('q')
return context
def get_queryset(self):
request = self.request
query_list = request.GET.get('q', None).split()
query_list_count = len(query_list)
if query_list is not None:
if query_list_count == 1:
qs = MyModel.objects.search(query=query_list[0]).order_by('-date_added')
self.count = len(qs)
elif query_list_count > 1:
qs = MyModel.objects.search_and(query=query_list).order_by('-date_added')
self.count = len(qs)
result_count = len(qs)
create_search_record(self, request, query_list, query_list_count, result_count)
return qs
对于 multi-word 字符串,神奇之处在于 reduce
函数,该函数针对给定的模型字段尝试所有关键字。这种经理模式的大部分功劳归功于 Justin Mitchel 的 excellent writeup on multi-model search.
我有一个搜索栏,正在搜索 2 个模型列标题,body,short_description。我am.usingMySQL数据库。现在,我正在使用 Q 查询,但我想 'improve'.
有一些搜索限制其中之一是 Q 查找仅基于与字段中完全相同的短语结果查找结果,例如,我有标题 why python is so amazing?
,我必须写 why
或 python
或 python is
以获得结果。我想要的是扩展搜索栏以按以下方式工作:
用户在搜索栏中插入一个问题:python language
并且搜索查找拆分每个单词并 returning 所有 object 包含 python
或 language
。最后,无论用户输入 python language
还是 amazing python
.
why python is so amazing?
我在下面发布我当前的代码:
views.py
def search_items(request):
query = request.GET.get('q')
article_list= Article.objects.filter(title__icontains=query)
qa_list = QA.objects.filter(title__icontains=query)
if query is not None:
lookups = Q(title__icontains=query) | Q(short_description__icontains=query) | Q(body__icontains=query)
article_list= Article.objects.filter(lookups, status=1).distinct()
qa_list = QA.objects.filter(lookups, status=1).distinct()
context = {
'query_name': query,
'article_list': article_list,
'qa_list': qa_list,
}
return render(request, 'search/search_items.html', context)
我检查了这个 solution and this one 但结果并不令人满意,因为当我输入 python language
来查找标题为 why python is so amazing
的 object 时,我没有得到任何结果.
问题
对于如何获得 objects 的结果以及基于用户在输入字段中输入的单词的所有 objects 的列表,我将不胜感激。
我 运行 遇到了同样的问题,并通过在我的模型上方的 models.py 中添加自定义搜索管理器解决了这个问题。管理器有两种方法,一种用于单词搜索,另一种用于multi-word。使用下面的 .split()
将查询字符串拆分为单词列表(参见视图)。
models.py
class MyModelSearchManager(models.QuerySet):
def search(self, query=None):
qs = self
if query is not None:
or_lookup = (Q(some_field__icontains=query))
qs = qs.filter(or_lookup).distinct()
return qs
def search_and(self, query=None):
qs = self
if query is not None:
or_lookup = reduce(lambda x, y: x & y, [Q(some_field__icontains=word) for word in query])
qs = qs.filter(or_lookup).distinct()
return qs
class MyModelManager(models.Manager):
def get_queryset(self):
return MyModelSearchManager(self.model, using=self._db)
def search(self, query=None):
return self.get_queryset().search(query=query)
def search_and(self, query=None):
return self.get_queryset().search_and(query=query)
当然,在您的模型字段下方声明自定义管理器:
objects = MyModelManager()
然后,在您看来,拆分搜索字符串并区分单词搜索和 multi-word 搜索:
class SearchView(ListView):
template_name = 'my_app_templates/search_results.html'
count = 0
def get_context_data(self, *args, **kwargs):
context = super().get_context_data(*args, **kwargs)
context['count'] = self.count or 0
context['query'] = self.request.GET.get('q')
return context
def get_queryset(self):
request = self.request
query_list = request.GET.get('q', None).split()
query_list_count = len(query_list)
if query_list is not None:
if query_list_count == 1:
qs = MyModel.objects.search(query=query_list[0]).order_by('-date_added')
self.count = len(qs)
elif query_list_count > 1:
qs = MyModel.objects.search_and(query=query_list).order_by('-date_added')
self.count = len(qs)
result_count = len(qs)
create_search_record(self, request, query_list, query_list_count, result_count)
return qs
对于 multi-word 字符串,神奇之处在于 reduce
函数,该函数针对给定的模型字段尝试所有关键字。这种经理模式的大部分功劳归功于 Justin Mitchel 的 excellent writeup on multi-model search.