当前位置: 首页 > news >正文

第15次:商品搜索

实现用户在页面可自由搜索某个商品的功能。

第1步:准备搜索功能用到的库

pip install whoosh
pip install jieba
pip install django-haystack
  • whoosh是搜索引擎,对英文支持较好,但对中文效果不佳。
  • jieba为中文分词库,弥补whoosh的缺陷。
  • django-haystack为在django项目中使用搜索引擎的工具应用,通过它可以在不修改代码的情况下使用不同的搜索引擎。

第2步:在settings.py中添加haystack应用

INSTALLED_APPS = ['django.contrib.admin','django.contrib.auth','django.contrib.contenttypes','django.contrib.sessions','django.contrib.messages','django.contrib.staticfiles','areas','carts','contents','goods','users','orders','payment','verifications','haystack'
]

第3步:在settings.py中新境搜索引擎whoosh的配置项

HAYSTACK_CONNECTIONS = {'default': {# 引擎使用whoosh'ENGINE': 'haystack.backends.whoosh_cn_backend.WhooshEngine',# 索引文件路径'PATH': os.path.join(BASE_DIR, 'whoosh_index')}
}
# 添加、修改、删除数据时,自动生成索引
HAYSTACK_SIGNAL_PROCESSOR = 'haystack.signals.RealtimeSignalProcessor'

第4步:将Whoosh自带的分词组件替换为jieba

在虚拟环境下(.venv\Lib\site-packages\haystack)创建ChineseAnalyzer.py

import jiebafrom whoosh.analysis import Tokenizer, Tokenclass ChineseTokenizer(Tokenizer):"""在 Whoosh 搜索引擎中, Token 对象是分词过程中的核心数据结构,主要作用包括:1. 存储分词信息 :- text : 分词后的实际文本内容- original : 原始分词文本(可能与处理后的不同)- boost : 权重值,影响搜索结果排序2. 记录位置信息 :- pos : 词在文本中的位置序号- startchar / endchar : 字符级别的起始和结束位置3. 控制索引行为 :- removestops : 是否移除停用词- mode : 控制索引模式(如存储位置信息等)"""def __call__(self, value, positions=False, chars=False, keeporiginal=False, removestops=True, start_pos=0,start_char=0, mode='', **kwargs):t = Token(positions, chars, removestops=removestops, mode=mode, **kwargs)seglist = jieba.cut(value, cut_all=True)for w in seglist:t.original = t.text = wt.boost = 1.0if positions:t.pos = start_pos + value.find(w)if chars:t.startchar = start_char + value.find(w)t.endchar = start_char + value.find(w) + len(w)yield tdef ChineseAnalyzer():return ChineseTokenizer()

复制/haystack/backends下的whoosh_backend.py文件,将副本更名为whoosh_cn_backend.py

打开whoosh_cn_backend.py,引入中文分析器文件ChineseAnalyzer.py

analyzer=field_class.analyzer or StemmingAnalyzer(),替换为analyzer = ChineseAnalyzer(),

在goods应用下创建索引类search_indexes.py,代码如下

from haystack import indexesfrom .models import SKUclass SKUIndex(indexes.SearchIndex, indexes.Indexable):"""索引数据模型类"""# 接收索引字段:使用文档定义索引字段,并且使用模板语法渲染# document=True表示该字段是主要进行关键字查询的字段,use_template=True表明后续要通过一个数据模板指明需要检索的字段text = indexes.CharField(document=True, use_template=True)def get_model(self):"""返回建立索引的模型类"""return SKUdef index_queryset(self, using=None):"""返回要建立索引的数据查询集"""return self.get_model().objects.filter(is_launched=True)

在templates/search/indexes/目录下创建goods目录,在其中创建sku_text.txt,在其中指定索引的属性。

{{object.id}}
{{object.name}}
{{object.caption}}

执行下面命令,手动生成初始索引

python .\manage.py rebuild_indexAre you sure you wish to continue? [y/N] y

在这里插入图片描述

在项目urls.py中增加haystack路由配置项

path('search/', include('haystack.urls')),

在templates/search/目录下新增搜索结果模板search.html

<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head><meta http-equiv="Content-Type" content="text/html;charset=UTF-8"><title>小鱼商城-商品搜索</title><link rel="stylesheet" type="text/css" href="{{ static('css/jquery.pagination.css') }}"><link rel="stylesheet" type="text/css" href="{{ static('css/reset.css') }}"><link rel="stylesheet" type="text/css" href="{{ static('css/main.css') }}"><script type="text/javascript" src="{{ static('js/jquery-1.12.4.min.js') }}"></script><script type="text/javascript" src="{{ static('js/vue-2.5.16.js') }}"></script><script type="text/javascript" src="{{ static('js/axios-0.18.0.min.js') }}"></script>
</head>
<body>
<div id="app"><div class="header_con"><div class="header" v-cloak><div class="welcome fl">欢迎来到小鱼商城!</div><div class="fr"><div v-if="username" class="login_btn fl">欢迎您:<em>[[ username ]]</em><span>|</span><a href="{{ url('users:logout') }}">退出</a></div><div v-else class="login_btn fl"><a href="{{ url('users:login') }}">登录</a><span>|</span><a href="{{ url('users:register') }}">注册</a></div><div class="user_link fl"><span>|</span><a href="{{ url('users:info') }}">用户中心</a><span>|</span>{#                    <a href="{{ url('carts:info') }}">我的购物车</a>#}<span>|</span>{#                    <a href="{{ url('users:myorderinfo',args=(1,)) }}">我的订单</a>#}</div></div></div></div><div class="search_bar clearfix"><a href="{{ url('contents:index') }}" class="logo fl"><img src="{{ static('images/logo.png') }}"></a><div class="search_wrap fl"><form method="get" action="/search/" class="search_con"><input type="text" class="input_text fl" name="q" placeholder="搜索商品"><input type="submit" class="input_btn fr" name="" value="搜索"></form><ul class="search_suggest fl"><li><a href="#">索尼微单</a></li><li><a href="#">优惠15元</a></li><li><a href="#">美妆个护</a></li><li><a href="#">买2免1</a></li></ul></div></div><div class="main_wrap clearfix"><div class="clearfix"><ul class="goods_type_list clearfix">{% for result in page %}<li><a href="detail.html"><img src="/static/images/goods/{{ result.object.default_image.url }}.jpg"></a><h4><a href="detail.html">{{ result.object.name }}</a></h4><div class="operate"><span class="price">¥{{ result.object.price }}</span><span>{{ result.object.comments }}评价</span><!--                        <span class="unit">{{ result.object.sales }}台</span>--><a href="#" class="add_goods" title="加入购物车"></a></div></li>{% else %}<p>没有找到您要查询的商品。</p>{% endfor %}</ul><div class="pagenation"><div id="pagination" class="page"></div></div></div></div><div class="footer"><div class="foot_link"><a href="#">关于我们</a><span>|</span><a href="#">联系我们</a><span>|</span><a href="#">招聘人才</a><span>|</span><a href="#">友情链接</a></div><p>CopyRight © 2024 北京小鱼商业股份有限公司 All Rights Reserved</p><p>电话:010-****888 京ICP备*******8号</p></div>
</div>
<script type="text/javascript" src="{{ static('js/common.js') }}"></script>
<script type="text/javascript" src="{{ static('js/search.js') }}"></script>
<script type="text/javascript" src="{{ static('js/jquery.pagination.min.js') }}"></script>
<script type="text/javascript">$(function () {$('#pagination').pagination({currentPage: {{ page.number }},totalPage: {{ paginator.num_pages }},callback: function (current) {window.location.href = '/search/?q={{ query }}&page=' + current;}})});
</script>
</body>
</html>

在settings.py中增加HAYSTACK_SEARCH_RESULT_PER_PAGE控制结果页面显示的搜索记录数量。

HAYSTACK_SEARCH_RESULTS_PER_PAGE = 5

http://www.dtcms.com/a/290146.html

相关文章:

  • Laravel 系统版本查看及artisan管理员密码找回方法针对各个版本通用方法及原理-优雅草卓伊凡
  • Java-78 深入浅出 RPC Dubbo 负载均衡全解析:策略、配置与自定义实现实战
  • LeetCode - 3274. Check if Two Chessboard Squares Have the Same Color
  • 【Semi笔记】Semisupervised Change Detection With Feature-Prediction Alignment
  • .NET SDK 9.0.200引入对SLNX解决方案文件的支持
  • compser json和lock的作用区别
  • 【qml-3】qml与c++交互第二次尝试(类型方式)
  • 【C++11】哈希表与无序容器:从概念到应用
  • ElasticSearch:不停机更新索引类型(未验证)
  • git switch
  • (LeetCode 面试经典 150 题) 219. 存在重复元素 II (哈希表)
  • taro微信小程序的tsconfig.json文件说明
  • 自动化与安全 - 将 Terraform 集成到 CI/CD
  • 编译支持cuda硬件加速的ffmpeg
  • 数据库和数据仓库的区别
  • day27 力扣332.重新安排行程 力扣51. N皇后 力扣37. 解数独 力扣455.分发饼干 力扣376. 摆动序列 力扣53. 最大子序和
  • 云原生周刊:K8s 中的后量子密码学
  • OpenCV计算机视觉实战(16)——图像分割技术
  • 微服务的编程测评系统-身份认证-管理员登录前端
  • LeetCode|Day21|204. 计数质数|Python刷题笔记
  • 【黑马SpringCloud微服务开发与实战】(四)微服务02
  • 随笔20250721 PostgreSQL实体类生成器
  • 【TVM 教程】TVM 代码库实例讲解
  • Spring AI 集成阿里云百炼与 RAG 知识库,实现专属智能助手(框架思路)
  • 若依前后端部署
  • Linux进程核心机制:状态、优先级与上下文切换详解
  • 基于Python flask的电影数据分析及可视化系统的设计与实现,可视化内容很丰富
  • 信息整合注意力IIA,通过双方向注意力机制重构空间位置信息,动态增强目标关键特征并抑制噪声
  • 文本数据分析
  • 数据分析的尽头是什么?是洞察,而非数字!