Django 配置搜索引擎 haystack 与 搜索页面无法返回数据问题

Django 配置搜索引擎 haystack 与 搜索页面无法返回数据问题

1、Django安装 haystack + whoosh + jieba

haystack是django的开源搜索框架,该框架支持Solr,Elasticsearch,Whoosh, 搜索引擎量。 Whoosh是一个搜索引擎使用,这是一个由纯Python实现的全文搜索引擎,没有二进制文件等,比较小巧,配置比较简单,性能略低。 Jieba是由Whoosh自带的是英文分词,对中文的分词支持不是太好,故用jieba替换whoosh的分词组件。

1pip install django-haystack 2pip install whoosh 3pip install jieba

image

2、创建项目app,配置settings.py文件

1# 全文检索框架haystack的配置 2HAYSTACK_CONNECTIONS = { 3 "default": { 4 # 指定使用的搜索引擎 5 'ENGINE': 'haystack.backends.whoosh_backend.WhooshEngine', 6 # 'ENGINE': 'haystack.backends.whoosh_cn_backend.WhooshEngine', 7 # 指定索引文件存放位置 8 'PATH': os.path.join(BASE_DIR, 'whoosh_index'), 9 'INCLUDE_SPELLING': True, 10 } 11} 12# 当添加、删除、修改数据时,自动生成索引 13HAYSTACK_SIGNAL_PROCESSOR = "haystack.signals.RealtimeSignalProcessor" 14# 每页显示条数 15HAYSTACK_SEARCH_RESULTS_PER_PAGE = 6

image

3、创建索引

在项目目录下创建​​search_indexes.py​​文件,文件名不能修改。

1from haystack import indexes 2# 对应模型 3from .models import Blog 4 5 6# 类名:模型名字 + Index 7class BlogIndex(indexes.SearchIndex, indexes.Indexable): 8 text = indexes.CharField(document=True, use_template=True) # 创建一个text字段 9 # blog_title = indexes.CharField(model_attr="blog_title") 10 # blog_content = indexes.CharField(model_attr="blog_content") 11 12 def get_model(self): 13 # 返回对应模型 14 return Blog 15 16 def index_queryset(self, using=None): 17 """Used when the entire index for model is updated.""" 18 return self.get_model().objects.all() 19

image

4、创建数据模板路径

blog/templates/search/indexes/blog/Blog_text.txt(模型名字 + _text.txt) 模板的作用是让text字段包含的内容,后面有搜索模板会用到。 txt中的内容根据模型类中需要进行搜索的字段进行设置。如我的models.py下的: image 博客文章的标题和内容(blog_title、blog_content)就是我搜索的字段。 image

5、配置路由

1from django.contrib import admin 2from django.urls import path, include 3from blog.views import * 4 5urlpatterns = [ 6 # path('admin/', admin.site.urls), 7 path('blog_index/', blog_index, name="blog_index"), 8 path('search/', include('haystack.urls')), 9]

image

6、创建search.html

在目录"templates/search/"下建立search.html作为检索结果返回的页面(可自己进行定制)

1{% extends 'Conventional_Template.html' %} 2{% load static %} 3 4{% block title %} 5 <title>搜索页面</title> 6{% endblock %} 7 8{% block section %} 9 10 <section id="bricks"> 11 <div class="row masonry"> 12 <div style="display: flex;justify-content: center;align-items: center;"> 13 <h1>含关键字 -{{ query }}- 的博客文章</h1> 14 </div> 15 <!-- brick-wrapper --> 16 <div class="bricks-wrapper"> 17 <div class="grid-sizer"></div> 18 {% if query %} 19 {% for result in page.object_list %} 20 <article class="brick entry animate-this"> 21 <div class="entry-thumb"> 22 <a href="#" class="thumb-link"> 23 <img src="{% static 'images/thumbs/liberty.jpg' %}" alt="Liberty"> 24 </a> 25 </div> 26 <div class="entry-text"> 27 <div class="entry-header"> 28 <div class="entry-meta"> 29 <span class="cat-links"> 30 <a>标签</a> 31 </span> 32 <span class="cat-links"> 33 <a>标签</a> 34 </span> 35 </div> 36 <h1 class="entry-title"><a href="#">{{ result.object.blog_title }}</a></h1> 37 </div> 38 <div class="entry-excerpt"> 39 {% autoescape off %} 40 {{ result.object.blog_content|striptags|truncatechars:150 }} 41 {% endautoescape %} 42 </div> 43 </div> 44 </article> 45 {% endfor %} 46 {% endif %} 47 </div> <!-- end brick-wrapper --> 48 </div> <!-- end row --> 49 50 <!-- 分页功能 --> 51 <div class="row"> 52 <nav class="pagination"> 53 {% if page.has_previous %} 54 <span class="page-numbers prev"> 55 <a href="?q={{ query }}&page={{ page.previous_page_number }}">Prev</a> 56 </span> 57 {% else %} 58 {% endif %} 59 60 {% for pindex in paginator.page_range %} 61 {% if pindex == page.number %} 62 <a href="?q={{ query }}&page={{ pindex }}" class="page-numbers">{{ pindex }}</a> 63 {% else %} 64 <a href="?q={{ query }}&page={{ pindex }}" class="page-numbers">{{ pindex }}</a> 65 {% endif %} 66 {% endfor %} 67 68 {% if page.has_next %} 69 <a href="?q={{ query }}&page={{ page.next_page_number }}" class="page-numbers next">Next</a> 70 {% else %} 71 {% endif %} 72 </nav> 73 </div> 74 </section> 75 76{% endblock %}

要注意修改路由路径,name="q"是固定的。 image

7、创建ChineseAnalyzer.py文件

chenzhanxu_blog\Lib\site-packages\haystack\backends (虚拟环境中-找到haystack下的backends 然后创建ChineseAnalyzer.py文件)

1import jieba 2from whoosh.analysis import Tokenizer, Token 3 4 5class ChineseTokenizer(Tokenizer): 6 def __call__(self, value, positions=False, chars=False, 7 keeporiginal=False, removestops=True, 8 start_pos=0, start_char=0, mode='', **kwargs): 9 t = Token(positions, chars, removestops=removestops, mode=mode, 10 **kwargs) 11 seglist = jieba.cut(value, cut_all=True) 12 for w in seglist: 13 t.original = t.text = w 14 t.boost = 1.0 15 if positions: 16 t.pos = start_pos + value.find(w) 17 if chars: 18 t.startchar = start_char + value.find(w) 19 t.endchar = start_char + value.find(w) + len(w) 20 yield t 21 22 23def ChineseAnalyzer(): 24 return ChineseTokenizer()

8、复制whoosh_backend.py文件,改名为whoosh_cn_backend.py

chenzhanxu_blog\Lib\site-packages\haystack\backends (虚拟环境中-找到haystack下的backends目录下的whoosh_backend.py,然后复制(复制的文件名末尾有个空格,记得删除)到当前目录下改名whoosh_cn_backend.py) 记得在whoosh_cn_backend.py文件中添加ChineseAnalyzer.py文件。

1from haystack.backends.ChineseAnalyzer 2import ChineseAnalyzer

然后查找whoosh_cn_backend.py文件中schema_fields[field_class.index_fieldname] = TEXT()。

1#schema_fields[field_class.index_fieldname] = TEXT( 2# stored=True, 3# analyzer=field_class.analyzer or StemmingAnalyzer(), 4# field_boost=field_class.boost, 5# sortable=True, 6# ) 7schema_fields[field_class.index_fieldname] = TEXT( 8 stored=True, analyzer=ChineseAnalyzer(), 9 field_boost=field_class.boost, 10 sortable=True, 11)

image

9、生成索引

1python manage.py rebuild_index 2# (可选更新索引)python manage.py update_index

如果在settings.py添加了​​HAYSTACK_SIGNAL_PROCESSOR = 'haystack.signals.RealtimeSignalProcessor'​就不用手动更新索引,系统会自动更新。 生成成功后在根目录下会生成一个whoosh_index的文件夹。 image

配置 haystack 搜索引擎的问题

1、search.html搜索页面无法返回数据问题

问题原因:可能是PyCharm创建Django是定义templates为模板文件,导致 haystack 无法自动找到templates文件夹,也就无法找到templates文件夹下的search.html模板,无法渲染成功。 解决方法:PyCharm创建Django项目时会把templates文件夹定义成为模板文件,要改成普通文件夹。 image

成品效果图 image image

个人博客:https://www.chenzhanxu.top/

点赞
收藏

评论区

加载中...

相关推荐

手把手教你使用Flask搭建ES搜索引擎(预备篇)

/1前言/Elasticsearch是一个开源的搜索引擎,建立在一个全文搜索引擎库ApacheLucene™基础之上。那么如何实现Elasticsearch和Python的对接成为我们所关心的问题了(怎么什么都要和Python关联啊)。/2 Python交互/所以,Python也就提供了可以对接Elasti

ES的索引结构与算法解析

提到ES,大多数爱好者想到的都是搜索引擎,但是明确一点,ES不等同于搜索引擎。不管是谷歌、百度、必应、搜狗为代表的自然语言处理(NLP)、爬虫、网页处理、大数据处理的全文搜索引擎,还是有明确搜索目的的搜索行为,如各大电商网站、OA、站内搜索、视频网站的垂直搜索引擎,他们或多或少都使用到了ES。

新版Chrome如何更换搜索引擎

一、地址栏更换搜索引擎SettingsSearchEngineManageserchenginesDefaultsearchengines或者Othersearchengines.由于我的Chrome是英文版,因此写成英文版本,对应中文设置搜索管理搜索引擎其他搜索引擎二、更换网页搜索引擎单击搜索引擎图标,点击添加/Add,输入http://

Elasticsearch与Solr优缺点比较

Elasticsearch简介Elasticsearch是一个实时的分布式搜索和分析引擎。它可以帮助你用前所未有的速度去处理大规模数据。它可以用于全文搜索,结构化搜索以及分析,也可以将这三者进行组合。Elasticsearch是一个建立在全文搜索引擎ApacheLucene™基础上的搜索引擎,可以说Lucen

ElasticSearch学习汇总

什么是ElasticSearch?ElasticSearch是一个基于Lucene的搜索服务器。它提供了一个分布式多用户能力的全文搜索引擎,基于RESTfulweb接口。Elasticsearch是用Java语言开发的,并作为Apache许可条款下的开放源码发布,是一种流行的企业级搜索引擎。ElasticSearch能够做到实时搜索并且稳定,

Chrome浏览器配置&小技巧(面向非技术人员)

注:本文仅面向电脑小白或者非技术人员分享一些常用的Chrome浏览器配置和小技巧一、管理搜索引擎进入搜索引擎管理界面:可以直接在地址栏右键修改搜索引擎,或者进入设置页面选择搜索引擎条目进入设置页面:单击浏览器右上角三点标志选择设置菜单,或者直接在地址栏输入:chrome://settings(chrome://settings