我建立一个搜索引擎,它需要一个自定义过滤器中显示文本周围的关键词,像在谷歌的摘录结果页。我正在使用正则表达式来识别周围的单词。这是我的过滤器代码:
@register.filter(needs_autoescape=True)
@stringfilter
def show_excerpt (value, search_term, autoescape=True):
# make the keyword put into the search engine case insensitive #
keywords = re.compile(re.escape(search_term), re.IGNORECASE)
# make excerpt return 300 characters before and after keyword #
excerpt_text = '.{300}' + str(keywords) + '.{300}'
# replace the original text with excerpt #
excerpt = value.sub(excerpt_text, value)
return mark_safe(excerpt)
准则按view.py搜索引擎:
def query_search(request):
articles = cross_currents.objects.all()
search_term = ''
if 'keyword' in request.GET:
search_term = request.GET['keyword']
articles = articles.annotate(similarity=Greatest(TrigramSimilarity('Title', search_term), TrigramSimilarity('Content', search_term))).filter(similarity__gte=0.03).order_by('-similarity')
context = {'articles': articles, 'search_term': search_term}
return render(request, 'query_search.html', context)
HTML模板(它包括一个自定义highlight
过滤器,该过滤器突出显示了放入搜索引擎的关键字):
<ul>
{% for article in articles %}
<li><a href="{% url 'search:article_detail' article.ArticleID %}">{{ article|highlight:search_term }}</a></li>
<p> {{ article.Content|highlight:search_term|show_excerpt:search_term }} </p>
{% endfor %}
</ul>
错误消息:“ SafeText”对象没有属性“ sub”
我认为我做错了.sub
。我只需要摘录更换整个原始文本(即我把在过滤器上的文字)。原始文本从数据的开头开始,但是我只想显示关键字周围的数据,我的highlight
自定义过滤器突出显示了关键字(就像在Google上一样)。任何想法?
编辑:当我做re.sub(excerpt_text, value)
,我得到的错误消息子()缺少1所需位置参数:字符串“”。
答案 0 :(得分:0)
您需要调用re.sub(),而不是value.sub()。您正在调用SafeText对象上的sub,.sub()是一个正则表达式函数。
我尚未测试您的代码,但是如果其余代码正确,则应将该行更改为re.sub(excerpt_text, value)
答案 1 :(得分:0)
我决定放弃正则表达式,只做旧的字符串切片。过滤器的工作代码:
@register.filter(needs_autoescape=True)
@stringfilter
def show_excerpt(value, search_term, autoescape=True):
#make data into string and lower#
original_text = str(value)
lower_original_text = original_text.lower()
#make keyword into string and lower#
keyword_string = str(search_term)
lower_keyword_string = keyword_string.lower()
#find the position of the keyword in the data#
keyword_index = lower_original_text.find(lower_keyword_string)
#Specify the begining and ending positions of the excerpt#
start_index = keyword_index - 10
end_index = keyword_index + 300
#Define the position range of excerpt#
excerpt = original_text[start_index:end_index]
return mark_safe(excerpt)