我的应用-基础知识
我有一个简单的django应用程序,它允许存储有关某些项目的信息,我正在尝试实现搜索视图/功能。
我使用django-taggit
来标记项目的功能/特性。
我想实现什么
我想实现一个全文搜索,允许搜索所有领域的项目,包括他们的标签。
问题
1.在结果视图中,标记的项目显示多次(每个标记出现一次)
1.当我在搜索字段中指定 * 只有一个 * 标签时,排名是正确的,但当我指定 * 多个 * 标签名称时,我会得到意想不到的排名结果。
我怀疑SearchVector()
没有像我期望的那样解析标签关系。在这种情况下,标签应该被视为单词列表。
示例代码
models.py
from django.db import models
from taggit.managers import TaggableManager
class Item(models.Model):
identifier = models.SlugField('ID', unique=True, editable=False)
short_text = models.CharField('Short Text', max_length=100, blank=True)
serial_number = models.CharField('Serial Number', max_length=30, blank=True)
revision = models.CharField('Revision/Version', max_length=30, blank=True)
part_number = models.CharField('Part Number', max_length=30, blank=True)
manufacturer = models.CharField('Manufacturer', max_length=30, blank=True)
description = models.TextField('Description', blank=True)
tags = TaggableManager('Tags', blank=True)
is_active = models.BooleanField('Active', default=True)
forms.py
from django import forms
class SearchForm(forms.Form):
search = forms.CharField(max_length=200, required=False)
active_only = forms.BooleanField(initial=True, label='Show active items only', required=False)
views.py
from django.views.generic.list import ListView
from django.contrib.postgres.search import SearchQuery, SearchVector, SearchRank
from . import models
from . import forms
class ItemListView(ListView):
form_class = forms.SearchForm
model = models.Item
fields = ['serial_number', 'part_number', 'manufacturer', 'tags', 'is_active']
template_name_suffix = '_list'
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['form'] = self.form_class(self.request.GET)
return context
def get_queryset(self):
queryset = super().get_queryset()
form = self.form_class(self.request.GET)
if form.is_valid():
if form.cleaned_data['active_only']:
queryset = queryset.filter(is_active=True)
if not form.cleaned_data['search']:
return super().get_queryset()
search_vector = SearchVector('identifier', 'short_text', 'serial_number', 'revision', 'part_number',
'manufacturer', 'description', 'tags')
search_query = SearchQuery(form.cleaned_data['search'], search_type='websearch')
return (
queryset.annotate(
search=search_vector, rank=SearchRank(search_vector, search_query)
)
# .filter(search=search_query)
.order_by("-rank").distinct()
) #.filter(search__icontains=form.cleaned_data['search'],)
return super().get_queryset()
1条答案
按热度按时间lp0sw83n1#
您的问题是将tags字段直接添加到
SearchVector
让我们将Django的
StringAgg
标签连接成一个字符串,然后在SearchVector
中使用该字符串首先我们导入
StringAgg
然后这就是你如何改变你的
get_queryset
函数