这里写目录标题
- 1 背景
- 2 Haystack 是什么
- 3 安装相关包,与配置
- 4 开启es和es可视化工具
- 5 生成索引
- 6 改代码
1 背景
Haystack 的官网
代码语言:javascript复制https://django-haystack.readthedocs.io/en/master/
2 Haystack 是什么
这个就是一个工具,就是连接django和es的中间的一个东西, Haystack 为 Django 提供模块化搜索。它具有统一、熟悉的 API,允许您插入不同的搜索后端(例如Solr、 Elasticsearch、Whoosh、Xapian等),而无需修改代码。
3 安装相关包,与配置
代码语言:javascript复制pip install drf-haystack
pip install elasticsearch==7.6.0
安装的elashsearch 版本要和你本地的一样,在启动的时候报错,就是确实依赖,提示缺少什么安装什么,最后都安装好之后,
1 注册应用
代码语言:javascript复制INSTALLED_APPS = [
...
'haystack',
...
]
就是要把haystack当做APP注册到项目里面
2 配置
在配置文件中配置haystack使用的搜索引擎后端
本地不同的es,就需要不同的版本,这个去官网找
3 之后创建索引类,这个就是和django里面model一样,因为model里面的每一个类代表一个表,所以我们需要新建一个文件夹,放es里面的实体类
在你对应要创建索引的表的APP的根目录下,创建这个文件
文件的名称必须是这个
代码语言:javascript复制search_indexes.py
里面的内容是
代码语言:javascript复制# 索引模型类的名称必须是 模型类名称 Index
from haystack import indexes
from .models import jtsgb
# 必须继承 indexes.SearchIndex, indexes.Indexable
class jtsgbIndex(indexes.SearchIndex, indexes.Indexable):
# 以下的字段,是es里面对应的字段
# 第一个必须这样写
text = indexes.CharField(document=True, use_template=True)
# 下面的就是和你model里面的一样了
name = indexes.CharField(model_attr='name')
zzxm = indexes.CharField(model_attr='zzxm')
# 必须这个写,返回的就是你的model名称
def get_model(self):
"""返回建立索引的模型类"""
return jtsgb
# 返回你的查询的结果,可以改成一定的条件的,但是格式就是这样
def index_queryset(self, using=None):
"""返回要建立索引的数据查询集"""
return self.get_model().objects.all()
4 在templates目录中创建text字段使用的模板文件 目录结构必须是这样
object可以理解为模型类的对象,搜索时,可以根据这三个字段来搜索,就是你es搜索,会根据那些字段进行查询,就会在这个文件里面配
以上都弄好之后,启动你的es,还有可视化工具
4 开启es和es可视化工具
5 生成索引
我们在django项目里面相当于已经集成了es,也配置了一些东西,那么现在就需要使用项目在es软件里面生成索引
手动生成初始索引
代码语言:javascript复制python manage.py rebuild_index
或者直接在pycharm软件里面,按照这个步骤
如果不报错,那么就成功了,就打开es软件
看到已经生成了索引库
并且索引库里面有数据了,rebuild_index 这个命令就是将我们MySQL数据库里面的数据同步到es里面,之后我们查询的的就是es,不是mysql了,所以我们在操作完mysql数据库之后,要及时的同步数据,或者写个定时器,进行同步数据;
6 改代码
我们现在完成的是将django集成了es,但是我们自己写的页面查询功能,如果改为查询es了?
第一步: 写个路由,view里面是类的形式,路由里面,类的后面一定要加括号
第二步,写对应的后台接口,就是写view
代码语言:javascript复制# 一定要继承SearchView
class MySearchView(SearchView):
# 重写人家的方法
def create_response(self):
# 人家的,就这样写,获取到的就是全部的东西
context = self.get_context()
data_list = []
# context['page'].object_list 这样获取到的就是 数据的list集合
for sku in context['page'].object_list:
# 获取表里面的数据,就是前缀就是sku.object
print(sku.object.name)
data_list.append({
'id': sku.object.id,
'name': sku.object.name,
'zzxm':sku.object.name,
'gszy':sku.object.gszy,
'sglx_id':sku.object.sglx_id,
'gmrq': sku.object.gmrq,
'ydsl': sku.object.ydsl,
'description': sku.object.description,
'thumbnail': sku.object.thumbnail,
'desc_pack': sku.object.desc_pack,
})
content = {}
if data_list:
content = {
'active_menu': 'homepage',
'xw_list': data_list,
}
else:
xw_list = jtsgb.objects.all()[0:1]
content = {
'active_menu': 'homepage',
'xw_list': xw_list,
}
# 渲染到我们自己写的页面
return render(self.request, 'index1.html', {"context":context,"content":content})
以上就开发完成一个接口。现在看前端,因为查询功能,前端需要模糊查询,而且还有分页,这个功能咋实现
首先我们要知道,我们可以在settings.py里面配置每页显示的数量 搜索结果每页显示数量 HAYSTACK_SEARCH_RESULTS_PER_PAGE = 3
前端往后端传的名称,必须是q
因为要实现分页功能,所以,我们先看接口返回的是什么
一个是自己封装的,一个是人家的,所以我们要实现分页,就需要用他的东西
代码语言:javascript复制 {% if context.page.has_previous %}
<li class="previous"><a
href="?q={{ context.query }}&page={{ context.page.previous_page_number }}">上一页</a>
</li>
{% else %}
<li class="previous disabled"><a href="#">上一页</a></li>
{% endif %}
第 {{ context.page.number }} / {{ context.page.paginator.num_pages }}页
{% if context.page.has_next %}
<li class="next"><a
href="?q={{ context.query }}&page={{ context.page.next_page_number }}">下一页</a>
</li>
{% else %}
<li class="next disabled"><a href="#">下一页</a></li>
{% endif %}
以上就实现了前后端的分离,与集成,如何判断他一定就是查询的es,而不是mysql,我们可以将mysql数据改了,看下查询出来的是什么,如果还是原来的,就是查询了es了,除非你重新更新了es了