如何分割用户在Django应用程序的输入字段中插入的单词



我有一个搜索栏,在两个模型列title、body、short_description中进行搜索。我正在使用MySQL数据库。现在,我正在使用Q查找,但有一些搜索限制,我想"改进"。

其中之一是Q查找仅根据与字段中完全相同的短语结果找到结果,因此例如,我的标题为why python is so amazing?,必须写whypythonpython is才能获得结果。我想得到的是以以下方式扩展搜索栏:

用户在搜索栏中插入一个问题:python language,搜索查找是拆分每个单词并返回包含pythonlanguage的所有对象。最终,无论用户放置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)

我已经检查了这个解决方案和这个解决方案,但结果并不令人满意,因为当我放置python language来查找标题为why python is so amazing的对象时,我没有得到任何结果。

问题

对于如何获得基于用户输入字段中的单词的所有对象列表的对象,我将不胜感激。

我遇到了同样的问题,并通过在模型上方的models.py中添加一个自定义搜索管理器来解决它。管理器有两种方法,一种用于单词搜索,另一种用于多词搜索。使用.split()将查询字符串拆分为单词列表(请参见下面的视图(。

型号.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()

然后,在您的视图中,拆分搜索字符串并区分单个单词搜索和多单词搜索:

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

对于多单词字符串,神奇之处在于reduce函数,它尝试针对给定的模型字段使用所有关键字。这种经理人模式在很大程度上归功于Justin Mitchel在多模式搜索方面的出色表现。

相关内容

  • 没有找到相关文章

最新更新