目前的代码为:
{% block main_body %}
<div class = "container">
<div class = "row">
<div class = "col-md-8 col-mid-offset-2">
{% if search_word == '' %}
<h3>您没有搜索任何内容。h3>
<hr>
<p>您可以尝试输入点什么, 例如:<a href="/search/?wd=浙江民营企业发展大厦">浙江民营企业发展大厦a>p>
{% else %}
<h5 style =" color: dimgrey ">搜索"{{ search_word }}", 共找到{{ search_result_count }}个结果h5>
{% for vo in page_of_search %}
<hr>
<h4 class="entry-title" style =" color: mediumblue"><a href="{% url vo.name %}"><u>{{ vo.name }}u>a>h4>
<p class="fa fa-map-marker"> 地址 :{{ vo.address }}p>
{% empty %}
<p>未找到要搜索的目标p>
{% endfor %}
{% endif %}
div>
div>
<div class = "row">
<ul class="pagination pagination-sm no-margin pull-right">
<li><a href="{% url 'search' %}?wd={{ search_word }}&page= 1">首页a>li>
{% if page_of_search.has_previous %}
<li><a class = "btn btn-default" href = "{% url 'search' %}?wd={{ search_word }}&page={{ page_of_search.previous_page_number }}">上一页a>li>
{% else %}
<li><a class = "btn btn-default" href = "{% url 'search' %}?wd={{ search_word }}&page= 1">上一页a>li>
{% endif %}
{% for p in plist %}
<li {% if p == page_of_search.number%}class="active" {% endif %}><a href="{% url 'search' %}?wd={{ search_word }}&page={{ p }}">{{p}}a>li>
{% endfor %}
{% if page_of_search.has_next %}
<li><a class = "btn btn-default" href = "{% url 'search' %}?wd={{ search_word }}&page={{ page_of_search.next_page_number }}">下一页a>li>
{% else %}
<li><a class = "btn btn-default" href = "{% url 'search' %}?wd={{ search_word }}&page= {{ maxpages }}">下一页a>li>
{% endif %}
<li><a href="{% url 'search' %}?wd={{ search_word }}&page= {{ maxpages }}">尾页a>li>
ul>
div>
div>
{% endblock %}
def search(request):
search_word = request.GET.get('wd', '')
if search_word == '':
building_result = Building.objects.filter(name__contains=search_word)
coperation_result = Corporation.objects.filter(name__contains=search_word)
else:
word_list = jieba.lcut(search_word, cut_all=True)
pattern = ''
for word in word_list:
pattern += '(?=.*' + word + ')'
building_result = Building.objects.filter(Q(name__iregex=pattern) | Q(address__iregex=pattern))
coperation_result = Corporation.objects.filter(Q(name__iregex=pattern) | Q(address__iregex=pattern))
tmp_content_list = set()
if building_result:
tmp_content_list = set(building_result)
# 最后将符合条件的文章标题模型和文章内容模型合并返回
info_list = set()
if coperation_result:
info_list = set(coperation_result)
# 在从文章标题模型中查找出最终汇总的模型返回
search_result_set = info_list.union(tmp_content_list)
search_result = list(search_result_set)
#分页
page = Paginator(search_result, 10) # 以每页10条数据分页
page_num = request.GET.get('page',1)
page_of_search = page.get_page(page_num)
maxpages = page.num_pages # 获取最大页数
plist = page.page_range # 获取页码列表信息
context = {'search_word':search_word, 'search_result':search_result,'search_result_count':len(search_result),'plist':plist,
'page_of_search':page_of_search,'maxpages':maxpages,}
return render(request, 'web/search.html',context)
目前的效果:
可以使用 Django 自带的 safe 过滤器和正则表达式来实现搜索关键词标红的效果。具体实现如下:
1.在模板中导入 re 模块。
{% load static %}
{% load humanize %}
{% load mytags %}
{% load myfilters %}
{% load mathfilters %}
{% load bootstrap3 %}
{% load staticfiles %}
{% load crispy_forms_tags %}
{% load i18n %}
{% load tz %}
{% load re %}
2.使用正则表达式来匹配搜索关键词,并用 span 标签将其包裹起来。
<h4 class="entry-title" style =" color: mediumblue"><a href="{% url vo.name %}"><u>{{ vo.name|safe|re_sub:search_word|safe }}</u></a></h4>
其中,re_sub 是一个自定义的模板过滤器,其代码如下:
import re
from django import template
register = template.Library()
@register.filter
def re_sub(value, arg):
"""
Replace all occurrences of the search string (arg) in the given string (value)
with a span tag that highlights the matched string.
"""
return re.sub(re.escape(arg), '<span class="highlight">\g<0></span>', value, flags=re.IGNORECASE)
这个过滤器会将所有匹配到的搜索关键词用 span 标签包裹起来,并添加一个 highlight 的 CSS 类来实现高亮效果。你可以根据需要修改这个 CSS 类的样式。
回答不易,希望对你有用,能够采纳。
首先,需要分析百度搜索的关键字标红功能,其实就是对输入的关键字进行字符串处理,以及HTML标签的解析;
然后,需要使用正则表达式,来获取输入的关键字,然后将关键字用HTML标签 等来包裹起来;
接着,使用浏览器的innerHTML方法,将获取到的HTML标签字符串渲染出来,完成输入的关键字标红功能。
该回答引用GPTᴼᴾᴱᴺᴬᴵ
你可以使用 re 模块对匹配到的搜索关键词进行替换,并添加标红的样式。具体代码如下:
import re
def search(request):
search_word = request.GET.get('wd', '')
if search_word == '':
building_result = Building.objects.filter(name__contains=search_word)
coperation_result = Corporation.objects.filter(name__contains=search_word)
else:
word_list = jieba.lcut(search_word, cut_all=True)
pattern = ''
for word in word_list:
pattern += '(?=.*' + word + ')'
building_result = Building.objects.filter(Q(name__iregex=pattern) | Q(address__iregex=pattern))
coperation_result = Corporation.objects.filter(Q(name__iregex=pattern) | Q(address__iregex=pattern))
tmp_content_list = set()
if building_result:
tmp_content_list = set(building_result)
# 最后将符合条件的文章标题模型和文章内容模型合并返回
info_list = set()
if coperation_result:
info_list = set(coperation_result)
# 在从文章标题模型中查找出最终汇总的模型返回
search_result_set = info_list.union(tmp_content_list)
search_result = list(search_result_set)
# 分页
page = Paginator(search_result, 10) # 以每页10条数据分页
page_num = request.GET.get('page',1)
page_of_search = page.get_page(page_num)
maxpages = page.num_pages # 获取最大页数
plist = page.page_range # 获取页码列表信息
# 关键词标红
for result in search_result:
for word in word_list:
result.name = re.sub(word, f'<span style="color:red">{word}</span>', result.name)
result.address = re.sub(word, f'<span style="color:red">{word}</span>', result.address)
context = {'search_word':search_word, 'search_result':search_result,'search_result_count':len(search_result),'plist':plist,
'page_of_search':page_of_search,'maxpages':maxpages,}
return render(request, 'web/search.html',context)
这样可以把搜索结果中匹配到的关键词标红显示。在 HTML 模板中需要使用 safe 过滤器,以保留 HTML 标签。
参考GPT和自己的思路,要实现在搜索结果中将关键词标记为红色,可以使用 HTML 标签 mark 包围关键词,并在 CSS 样式中设置红色。可以通过使用 Django 自带的 safe 过滤器来避免 HTML 标签被转义,以便在搜索结果中正常显示标记。
以下是一个修改后的代码示例:
{% block main_body %}
<div class="container">
<div class="row">
<div class="col-md-8 col-mid-offset-2">
{% if search_word == '' %}
<h3>您没有搜索任何内容。</h3>
<hr>
<p>您可以尝试输入点什么,例如:<a href="/search/?wd=浙江民营企业发展大厦">浙江民营企业发展大厦</a></p>
{% else %}
<h5 style="color: dimgrey">搜索"{{ search_word }}", 共找到{{ search_result_count }}个结果</h5>
{% for vo in page_of_search %}
<hr>
<h4 class="entry-title" style="color: mediumblue"><a href="{% url vo.name %}"><u>{{ vo.name|safe|highlight:search_word }}</u></a></h4>
<p class="fa fa-map-marker"> 地址:{{ vo.address|safe|highlight:search_word }}</p>
{% empty %}
<p>未找到要搜索的目标</p>
{% endfor %}
{% endif %}
</div>
</div>
<div class="row">
<ul class="pagination pagination-sm no-margin pull-right">
<li><a href="{% url 'search' %}?wd={{ search_word }}&page=1">首页</a></li>
{% if page_of_search.has_previous %}
<li><a class="btn btn-default" href="{% url 'search' %}?wd={{ search_word }}&page={{ page_of_search.previous_page_number }}">上一页</a></li>
{% else %}
<li><a class="btn btn-default" href="{% url 'search' %}?wd={{ search_word }}&page=1">上一页</a></li>
{% endif %}
{% for p in plist %}
<li {% if p == page_of_search.number %}class="active" {% endif %}><a href="{% url 'search' %}?wd={{ search_word }}&page={{ p }}">{{ p }}</a></li>
{% endfor %}
{% if page_of_search.has_next %}
<li><a class="btn btn-default" href="{% url 'search' %}?wd={{ search_word }}&page={{ page_of_search.next_page_number }}">下一页</a></li>
{% else %}
<li><a class="btn btn-default" href="{% url 'search' %}?wd={{ search_word }}&page={{ maxpages }}">下一页</a></li>
{% endif %}
<li><a href="{% url 'search' %}?wd={{ search_word }}&page={{ maxpages }}">尾页</a></li>
</ul>
</div>
</div>
{% endblock %}
要实现和百度搜索一样的输入的关键字标红,您可以按照以下步骤进行操作:
在模板中使用safe过滤器将搜索结果中的名称和地址等文本包裹在一个span标签中,并添加一个名为highlight的CSS类,如下所示:
<h4 class="entry-title" style="color: mediumblue"><a href="{% url vo.name %}"><u><span class="highlight">{{ vo.name|safe }}</span></u></a></h4>
<p class="fa fa-map-marker"> 地址:<span class="highlight">{{ vo.address|safe }}</span></p>
在CSS文件中定义一个名为highlight的类,指定文本的背景颜色为黄色(或其他您喜欢的颜色),如下所示:
.highlight {
background-color: yellow;
}
在Python代码中使用re.sub()函数将搜索词替换为带有highlight类的文本,如下所示:
import re
...
for vo in page_of_search:
# 将搜索词替换为带有highlight类的文本
name = re.sub(search_word, f'<span class="highlight">{search_word}</span>', vo.name, flags=re.IGNORECASE)
address = re.sub(search_word, f'<span class="highlight">{search_word}</span>', vo.address, flags=re.IGNORECASE)
# 渲染模板时使用替换后的文本
context['search_result'].append({'name': name, 'address': address})
注意:在使用re.sub()函数替换文本时,为了匹配大小写不敏感的搜索词,需要使用flags=re.IGNORECASE参数。
以下是实现输入的关键字标红的代码示例:
{% block main_body %}
<div class = "container">
<div class = "row">
<div class = "col-md-8 col-mid-offset-2">
{% if search_word == '' %}
<h3>搜索任何内容。</h3>
<hr>
<p>尝试输入点什么, 例如:<a href="/search/?wd="></a></p>
{% else %}
<h5 style =" color: dimgrey ">搜索"{{ search_word }}", 共找到{{ search_result_count }}个结果</h5>
{% for vo in page_of_search %}
<hr>
<h4 class="entry-title" style =" color: mediumblue"><a href="{% url vo.name %}"><u>{{ vo.name|highlight:search_word }}</u></a></h4>
<p class="fa fa-map-marker"> 地址 :{{ vo.address|highlight:search_word }}</p>
{% empty %}
<p>未找到要搜索的目标</p>
{% endfor %}
{% endif %}
</div>
</div>
<div class = "row">
<ul class="pagination pagination-sm no-margin pull-right">
<li><a href="{% url 'search' %}?wd={{ search_word }}&page= 1">首页</a></li>
{% if page_of_search.has_previous %}
<li><a class = "btn btn-default" href = "{% url 'search' %}?wd={{ search_word }}&page={{ page_of_search.previous_page_number }}">上一页</a></li>
{% else %}
<li><a class = "btn btn-default" href = "{% url 'search' %}?wd={{ search_word }}&page= 1">上一页</a></li>
{% endif %}
{% for p in plist %}
<li {% if p == page_of_search.number%}class="active" {% endif %}><a href="{% url 'search' %}?wd={{ search_word }}&page={{ p }}">{{p}}</a></li>
{% endfor %}
{% if page_of_search.has_next %}
<li><a class = "btn btn-default" href = "{% url 'search' %}?wd={{ search_word }}&page={{ page_of_search.next_page_number }}">下一页</a></li>
{% else %}
<li><a class = "btn btn-default" href = "{% url 'search' %}?wd={{ search_word }}&page= {{ maxpages }}">下一页</a></li>
{% endif %}
<li><a href="{% url 'search' %}?wd={{ search_word }}&page= {{ maxpages }}">尾页</a></li>
</ul>
</div>
</div>
{% endblock %}
在模板中,我们对搜索结果的名称和地址应用了一个名为“highlight”的自定义模板标签。这个标签的作用是在匹配搜索关键字时,将其用<span>标签包围,以便通过CSS样式来高亮显示。
以下是自定义“highlight”标签的代码:
from django import template
register = template.Library()
@register.filter
def highlight(text, search):
highlighted = text.replace(search)
下一步是对搜索结果中的关键词进行标红。可以使用Python的正则表达式来实现这个功能。具体步骤如下:
将搜索词分词并用空格拼接成正则表达式的模式。
遍历搜索结果列表中的每一个结果对象,将结果对象中的name和address属性中的匹配搜索词的部分用html标签将其标红。
将标红后的结果对象添加到新的列表中,最终将新列表作为搜索结果返回给前端。
import re
def search(request):
search_word = request.GET.get('wd', '')
if search_word == '':
building_result = Building.objects.filter(name__contains=search_word)
coperation_result = Corporation.objects.filter(name__contains=search_word)
else:
word_list = jieba.lcut(search_word, cut_all=True)
pattern = ''
for word in word_list:
pattern += '(?=.*' + word + ')'
building_result = Building.objects.filter(Q(name__iregex=pattern) | Q(address__iregex=pattern))
coperation_result = Corporation.objects.filter(Q(name__iregex=pattern) | Q(address__iregex=pattern))
tmp_content_list = set()
if building_result:
tmp_content_list = set(building_result)
# 最后将符合条件的文章标题模型和文章内容模型合并返回
info_list = set()
if coperation_result:
info_list = set(coperation_result)
# 在从文章标题模型中查找出最终汇总的模型返回
search_result_set = info_list.union(tmp_content_list)
search_result = list(search_result_set)
# 对搜索结果中的关键词进行标红
if search_word:
pattern = '|'.join(word_list)
for result in search_result:
result.name = re.sub(pattern, lambda x: '<span style="color:red">' + x.group() + '</span>', result.name)
result.address = re.sub(pattern, lambda x: '<span style="color:red">' + x.group() + '</span>', result.address)
#分页
page = Paginator(search_result, 10) # 以每页10条数据分页
page_num = request.GET.get('page',1)
page_of_search = page.get_page(page_num)
maxpages = page.num_pages # 获取最大页数
plist = page.page_range # 获取页码列表信息
context = {'search_word':search_word, 'search_result':search_result,'search_result_count':len(search_result),'plist':plist,
'page_of_search':page_of_search,'maxpages':maxpages,}
return render(request, 'web/search.html',context)
需要注意的是,在前端页面中需要使用safe过滤器来将标红后的HTML代码正常显示,例如:
<h4 class="entry-title" style="color: mediumblue"><a href="{% url vo.name %}">{{ vo.name|safe }}</a></h4>
<p class="fa fa-map-marker"> 地址:{{ vo.address|safe }}</p>
最简单直接的可以直接用一个replace把内容替换关键字为
```
<span class="red"》关键字《/span>
```然后在css里设置样式就好了
您可以使用 Django 内置的 highlight 模板标签来高亮显示搜索关键字
{% block main_body %}
<div class="container">
<div class="row">
<div class="col-md-8 col-mid-offset-2">
{% if search_word == '' %}
<h3>您没有搜索任何内容。</h3>
<hr>
<p>您可以尝试输入点什么,例如:<a href="/search/?wd=浙江民营企业发展大厦">浙江民营企业发展大厦</a></p>
{% else %}
<h5 style="color: dimgrey">搜索"{{ search_word }}", 共找到{{ search_result_count }}个结果</h5>
{% for vo in page_of_search %}
<hr>
<h4 class="entry-title" style="color: mediumblue">
<a href="{% url vo.name %}">
<u>{{ vo.name|highlight:search_word }}</u>
</a>
</h4>
<p class="fa fa-map-marker"> 地址:{{ vo.address|highlight:search_word }}</p>
{% empty %}
<p>未找到要搜索的目标</p>
{% endfor %}
{% endif %}
</div>
</div>
<div class="row">
<ul class="pagination pagination-sm no-margin pull-right">
<li><a href="{% url 'search' %}?wd={{ search_word }}&page=1">首页</a></li>
{% if page_of_search.has_previous %}
<li>
<a class="btn btn-default" href="{% url 'search' %}?wd={{ search_word }}&page={{ page_of_search.previous_page_number }}">
上一页
</a>
</li>
{% else %}
<li>
<a class="btn btn-default" href="{% url 'search' %}?wd={{ search_word }}&page=1">
上一页
</a>
</li>
{% endif %}
{% for p in plist %}
<li {% if p == page_of_search.number%}class="active" {% endif %}>
<a href="{% url 'search' %}?wd={{ search_word }}&page={{ p }}">{{ p }}</a>
</li>
{% endfor %}
{% if page_of_search.has_next %}
<li>
<a class="btn btn-default" href="{% url 'search' %}?wd={{ search_word }}&page={{ page_of_search.next_page_number }}">
下一页
</a>
</li>
{% else %}
<li>
<a class="btn btn-default" href="{% url 'search' %}?wd={{ search_word }}&page={{ maxpages }}">
下一页
</a>
</li>
{% endif %}
<li><a href="{% url 'search' %}?wd={{ search_word }}&page={{ maxpages }}">尾页</a></li>
</ul>
</div>
</div>
{% endblock %}
上述模板代码中,highlight 过滤器将使用搜索关键字高亮显示搜索结果页面中的名称和地址。