Django全文搜索功能

1. 使用全文搜索框架django-haystack

2. 使用搜索引擎whoosh

3. 安装

  pip install django-haystack

  pip install whoosh

4. 配置

settings.py中

INSTALLED_APPS = [
  ...
'haystack',
'app01',
]

# 全文检索框架配置
HAYSTACK_CONNECTIONS = {
'default': {
# whoosh引擎
'ENGINE': 'haystack.backends.whoosh_backend.WhooshEngine',
# 索引文件路径
'PATH': os.path.join(BASE_DIR, 'whoosh_index'),
}
}

# 当添加,修改,删除数据时,自动生成索引
HAYSTACK_SIGNAL_PROCESSOR = 'haystack.signals.RealtimeSignalProcessor'

5. 文件生成

  1. 在app文件夹下建立一个py文件,文件名是固定的search_indexes.py

from haystack import indexes
# 导入该app下的模型类
from goods.models import GoodsSKU


# 指定对于某个类的某些数据(字段)建立索引
# 索引类名格式:模型类名+Index
class GoodsSKUIndex(indexes.SearchIndex, indexes.Indexable):
# 索引字段 use_template=True指定根据表中的哪些字段建立索引文件的说明放在一个文件中
text = indexes.CharField(document=True, use_template=True)

def get_model(self):
# 返回你的模型类
return GoodsSKU

def index_queryset(self, using=None):
return self.get_model().objects.all()

  2. 在templates下面建立文件夹templates/search/indexes/goods/goodssku_text.txt,写入以下内容

    其中标红的两个名字一个是app名称,一个是模型类名小写加_text,路径及文件名也是固定的

# 指定根据表中的哪些字段建立索引数据
# {{ object.字段名 }} ,接受跨表字段名
{{ object.name }}  # 根据商品的名称建立索引
{{ object.desc }}  # 根据商品的简介建立索引
{{ object.goods.detail }}  # 根据商品的详情建立索引

  3. 环境终端运行python manage.py rebuild_index. 此时就会生成一个新文件夹,可以尝试

6. 使用全文检索

  1. 前端页面提交表单到一个url中进行处理,建议url设置为/search

get请求,请求地址为/search

<div class="search_con fl"> <form method="get" action="/search"> <input type="text" class="input_text fl" name="q" placeholder="搜索商品"> <input type="submit" class="input_btn fr" name="" value="搜索"> </form> </div>

  2. 配置url

固定写法,当有请求发送过来是,交给haystack.urls进行处理

urlpatterns = [ url(r'^admin/', admin.site.urls), url(r'^tinymce/', include('tinymce.urls')), url(r'^search', include('haystack.urls')), # 加入这一行   ... ]

  3.  请求的返回结果

当请求传达给haystack后,Haystack会把搜索出的结果传递给templates/search下的search.html(需要手动创建)
①传递的上下文包括:
1)query:搜索关键字
2)page: 当前页的page对象-->遍历page对象,获取到的是SearchResult类的实例对象,对象的属性object才是模型类的对象
3)paginator:分页paginator对象,
4)通过在settings.py中设置HAYSTACK_SEARCH_RESULTS_PER_PAGE = 1 每页显示数量

7. 前端显示(这里还没有弄明白)

            <ul class="goods_type_list clearfix">

                {% for res in page %}

                <li>
                    <a href="{% url 'goods:detail' res.object.id %}"><img src="{{ res.object.image.url }}"></a>
                    <h4><a href="{% url 'goods:detail' res.object.id %}">{{ res.object.name }}</a></h4>
                    <div class="operate">
                        <span class="prize">¥{{ res.object.price }}</span>
                        <span class="unit">{{ res.object.price }}/{{ res.object.unite }}</span>
                        <a href="#" class="add_goods" title="加入购物车"></a>
                    </div>
                </li>

                {% endfor %}

            </ul>

            <div class="pagenation">
                {% if page.has_previous %}
                    <a href="/search?q={{ query }}&page={{ page.previous_page_number }}">上一页</a>
                {% endif %}

                {% for pindex in paginator.page_range %}
                    {% if pindex == page.number %}
                        <a href="/search?q={{ query }}&page={{ pindex }}" class="active">{{ pindex }}</a>
                        {% else %}
                        <a href="/search?q={{ query }}&page={{ pindex }}">{{ pindex }}</a>
                    {% endif %}

                {% endfor %}


                {% if page.has_next %}
                    <a href="/search?q={{ query }}&page={{ page.next_page_number }}">下一页></a>
                {% endif %}

            </div>

8. 使用jieba分词,效果比haystark默认的要好很多

pip install jieba

# 然后在文件夹/python路径/lib/python2.7.5/site-packages/haystack/backends/whoosh_backend.py ,
将里面的whoosh_backend.py复制一份还在此文件夹下,改名为whoosh_cn_backend.py,并修改两行代码

from jieba.analyse import ChineseAnalyzer #在顶部添加

schema_fields[field_class.index_fieldname] = TEXT(stored=True, analyzer=ChineseAnalyzer(),field_boost=field_class.boost, sortable=True) #找到这个然后修改,大概在160行

# 然后在settings.py中修改配置

 
 
# 全文检索框架配置
HAYSTACK_CONNECTIONS = {
'default': {
# whoosh引擎
'ENGINE': 'haystack.backends.whoosh_cn_backend.WhooshEngine',
# 索引文件路径
'PATH': os.path.join(BASE_DIR, 'whoosh_index'),
}
}
具体参考:https://blog.csdn.net/ac_hell/article/details/52875927

猜你喜欢

转载自www.cnblogs.com/JackShi/p/12803183.html