django-haystack全⽂检索详细教程
前⼏天要⽤Django-haystack来实现搜索功能,⽹上⼀搜中⽂资源少之⼜少,虽说有官⽅⽂档,但相信对于我们这些英语差的同学来说要看懂真的是⼀件难事。特别是关于⾼级部分,特地了个英语专业的来翻译,也没能看出个名堂来,专业性实在是太强了,导致完全看不懂。。。
但是,对于⼀些⼩站点的开发来说,下⾯我要给⼤家讲的完全⾜够⽤了,只不过有时候确实⿇烦点。好了,⾔归正传。为了节约时间,简单设置部分从⽹上了⼀篇博客,但是这边⽂章没有解释配置的作⽤,⽽我会给你们详细解释并拓展。
转载部分来⾃:
⼀:使⽤的⼯具
是django的开源搜索框架,该框架⽀持,Elasticsearch,Whoosh, *Xapian*搜索引擎,不⽤更改代码,直接切换引擎,减少代码量。
搜索引擎使⽤,这是⼀个由纯Python实现的全⽂搜索引擎,没有⼆进制⽂件等,⽐较⼩巧,配置⽐较简单,当然性能⾃然略低。
中⽂分词,由于Whoosh⾃带的是英⽂分词,对中⽂的分词⽀持不是太好,故⽤jieba替换whoosh的分词组件。
其他:Python 2.7 or 3.4.4, Django 1.8.3或者以上,Debian 4.2.6_3
⼆:配置说明
现在假设我们的项⽬叫做Project,有⼀个myapp的app,简略的⽬录结构如下。
Project
Project
settings.py
blog
models.py
此models.py的内容假设如下:
from django.db import models
dels import User
class Note(models.Model):
user = models.ForeignKey(User)
pub_date = models.DateTimeField()
title = models.CharField(max_length=200)
body = models.TextField()
def __str__(self):
return self.title
1. ⾸先安装各⼯具
pip install whoosh django-haystack jieba
2. 添加 Haystack 到Django的 INSTALLED_APPS
配置Django项⽬的settings.py⾥⾯的INSTALLED_APPS添加Haystack,例⼦:
INSTALLED_APPS = [
'ib.admin',
'ib.auth',
'ttypes',
'ib.sessions',
'ib.sites',
# Added. haystack先添加,
'haystack',
# Then your ⾃⼰的app要写在haystakc后⾯
'blog',
]
3. 修改你的 settings.py,以配置引擎
本教程使⽤的是Whoosh,故配置如下:
import os
HAYSTACK_CONNECTIONS = {
'default': {
'ENGINE': 'haystack.backends.whoosh_backend.WhooshEngine',
'PATH': os.path.join(os.path.dirname(__file__), 'whoosh_index'),
},
}
其中顾名思义,ENGINE为使⽤的引擎必须要有,如果引擎是Whoosh,则PATH必须要填写,其为Whoosh 索引⽂件的存放⽂件夹。
其他引擎的配置见
4.创建索引
如果你想针对某个app例如mainapp做全⽂检索,则必须在mainapp的⽬录下⾯建⽴search_indexes.py⽂件,⽂件名不能修改。内容如下:
import datetime
from haystack import indexes
dels import Note
class NoteIndex(indexes.SearchIndex, indexes.Indexable): #类名必须为需要检索的Model_name+Index,这⾥需要检索Note,所以创建NoteIndex text = indexes.CharField(document=True, use_template=True) #创建⼀个text字段
author = indexes.CharField(model_attr='user') #创建⼀个author字段
pub_date = indexes.DateTimeField(model_attr='pub_date') #创建⼀个pub_date字段
def get_model(self): #重载get_model⽅法,必须要有!
return Note
def index_queryset(self, using=None): #重载index_..函数
"""Used when the entire index for model is updated."""
_model().objects.filter(pub_date__lte=w())
为什么要创建索引?索引就像是⼀本书的⽬录,可以为读者提供更快速的导航与查。在这⾥也是同样的道理,当数据量⾮常⼤的时候,若要从这些数据⾥出所有的满⾜搜索条件的⼏乎是不太可能的,将会给服务器带来极⼤的负担。所以我们需要为指定的数据添加⼀个索引(⽬录),在这⾥是为Note创建⼀个索引,索引的实现细节是我们不需要关⼼的,⾄于为它的哪些字段创建索引,怎么指定,正是我要给⼤家讲的,也是⽹上所不曾提到的。
每个索引⾥⾯必须有且只能有⼀个字段为 document=True,这代表haystack 和搜索引擎将使⽤此字段的内容作为索引进⾏检索(primary field)。其他的字段只是附属的属性,⽅便调⽤,并不作为检索数据。直到我⾃⼰完成⼀个搜索器,也没有⽤到这些附属属性,所以我索性就都删掉了,⼤家学习的时候也可以先注释掉不管。具体作⽤我也不明⽩,反正我没⽤上。
注意:如果使⽤⼀个字段设置了document=True,则⼀般约定此字段名为text,这是在SearchIndex类⾥⾯⼀贯的命名,以防⽌后台混乱,当然名字你也可以随便改,不过不建议改。
并且,haystack提供了use_template=True在text字段,这样就允许我们使⽤数据模板去建⽴搜索引擎索引的⽂件,说得通俗点就是索引⾥⾯需要存放⼀些什么东西,例如 Note 的 title 字段,这样我们可以通过 title 内容来检索 Note 数据了,举个例⼦,假如你搜索 python ,那么就可以检索出含有title含有 python 的Note了,怎么样是不是很简单?数据模板的路径
为templates/search/indexes/yourapp/(推荐在项⽬根⽬录创建⼀个templates,并在settings.py⾥为其引⼊,使得django会从这个templates⾥寻模板,当然,只要放在任何⼀个你的Django能搜索到的tempaltes下⾯就好,关于这点我想不属于我们讨论的范
畴),templates/search/indexes/blog/⽂件名必须为要索引的类名_,其内容为
{{ object.title }}
{{ _full_name }}
{{ object.body }}
这个数据模板的作⽤是对Note.title, _full_name,Note.body这三个字段建⽴索引,当检索的时候会对这三个字段做全⽂检索匹配。上⾯已经解释清楚了。
5.在URL配置中添加SearchView,并配置模板
在urls.py中配置如下url信息,当然url路由可以随意写。
(r'^search/', include('haystack.urls')),
其实 haystack.urls 的内容为
f.urls import url
from haystack.views import SearchView
urlpatterns = [
url(r'^$', SearchView(), name='haystack_search'),
]
SearchView()视图函数默认使⽤的html模板路径为templates/search/search.html(再说⼀次推荐在根⽬录创建templates,并在settings.py⾥设置好)
所以需要在templates/search/下添加search.html⽂件,内容为
<h2>Search</h2>
<form method="get" action=".">
<table>
{{ form.as_table }}
<tr>
<td> </td>
<td>
<input type="submit" value="Search">
</td>
</tr>
</table>
{% if query %}
<h3>Results</h3>
{% for result in page.object_list %}
<p>
<a href="{{ _absolute_url }}">{{ result.object.title }}</a>
</p>
{% empty %}
<p>No results found.</p>
{% endfor %}
{% if page.has_previous or page.has_next %}
<div>
{% if page.has_previous %}<a href="?q={{ query }}&page={{ page.previous_page_number }}">{% endif %}« Previous{% if page.has_previous %}</a> |
{% if page.has_next %}<a href="?q={{ query }}&page={{ _page_number }}">{% endif %}Next »{% if page.has_next %}</a>{% endif %}
python官方文档中文版</div>
{% endif %}
{% else %}
{# Show some example queries to run, maybe query syntax, something else? #}
{% endif %}
</form>
很明显,它⾃带了分页。
然后为⼤家解释⼀下这个⽂件。⾸先可以看到模板⾥使⽤了的变量有 form,query,page 。下⾯⼀个个的说⼀下。
form,很明显,它和django⾥的form类是差不多的,可以渲染出⼀个搜索的表单,相信⽤过Django的Form都知道,所以也不多说了,不
明⽩的可以去看Django⽂档,当然其实我倒最后也没⽤上,最后是⾃⼰写了个<form></form>,提供正确的参数
如name="seach",method="get"以及你的action地址就OK了。。。如果需要⽤到更多的搜索功能如过滤的话可能就要⾃定义Form类了
(⽽且通过上⾯的例⼦可以看到,默认的form也是提供⼀个简单的过滤器的,可以供你选择哪些model是需要检索的,如果⼀个都不勾的
话默认全部搜索,当然我们也是可以⾃⼰利⽤html来模拟这个form的,所以想要实现model过滤还是很简单的,只要模拟⼀下这个Form的
内容就好了),只有这样haystack才能够构造出相应的Form对象来进⾏检索,其实和django的Form是⼀样的,Form有⼀个⾃我检查数
据是否合法的功能,haystack也⼀样,关于这个此篇⽂章不做多说,因为我也不太明⽩(2333)。具体细节去看⽂档,⽽且⽂档上关于
View&Form那⼀节还是⽐较通俗易懂的,词汇量要求也不是很⾼,反正就连我都看懂了⼀些。。。
query嘛,就是我们搜索的字符串。
关于page,可以看到page有object_list属性,它是⼀个list,⾥⾯包含了第⼀页所要展⽰的model对象集合,那么list⾥⾯到底有多少个
呢?我们想要⾃⼰控制个数怎么办呢?不⽤担⼼,haystack为我们提供了⼀个接⼝。我们只要在settings.py⾥设置:
#设置每页显⽰的数⽬,默认为20,可以⾃⼰修改
HAYSTACK_SEARCH_RESULTS_PER_PAGE = 8
然后关于分页的部分,⼤家看名字应该也能看懂吧。
如果想要知道更多的默认context带的变量,可以⾃⼰看看源码views.py⾥的SearchView类视图,相信都能看懂。
那么问题来了。对于⼀个search页⾯来说,我们肯定会需要⽤到更多⾃定义的 context 内容,那么这下该怎么办呢?最初我想到的办法便是修改haystack源码,为其添加上更多的 context 内容,你们是不是也有过和我⼀样的想法呢?但是这样做即笨拙⼜愚蠢,我们不仅需要注意各种环境,依赖关系,⽽且当服务器主机发⽣变化时,难道我们还要把 haystack 也复制过去不成?这样太愚蠢了!突然,我想到既然我不能修改源码,难道我还不能复⽤源码吗?之后,我⽤看了⼀下官⽅⽂档,正如我所想的,通过继承SeachView来实现重载 context 的内容。官⽅⽂档提供了2个版本的SearchView,我最开始⽤的是新版的,最后出错了,也懒得去错误是什么引起的了,直接使⽤的了旧版本的SearchView,只要你下了haystack,2个版本都是给你安装好了的。于是我们在myapp⽬录下再创建⼀个search_views.py ⽂件,位置名字可以⾃⼰定,⽤于写⾃⼰的搜索视图,代码实例如下:
from haystack.views import SearchView
from .models import *
class MySeachView(SearchView):
def extra_context(self): #重载extra_context来添加额外的context内容
context = super(MySeachView,self).extra_context()
side_list = Topic.objects.filter(kind='major').order_by('add_date')[:8]
context['side_list'] = side_list
return context
然后再修改urls.py将search请求映射到 MySearchView:
url(r'^search/', search_views.MySeachView(), name='haystack_search'),
讲完了上下⽂变量,再让我们来讲⼀下模板标签,haystack为我们提供了 {% highlight %}和 {% more_like_this %} 2个标签,这⾥我只为⼤家详细讲解下 highlight的使⽤。
你是否也想让⾃⼰的检索和百度搜索⼀样,将匹配到的⽂字也⾼亮显⽰呢? {% highlight %} 为我们提供了这个功能(当然不仅是这个标签,貌似还有⼀个HighLight类,这个⾃⼰看⽂档去吧,我英语差,看不明⽩)。
Syntax:
{% highlight <text_block> with <query> [css_class "class_name"] [html_tag "span"] [max_length 200] %}
⼤概意思是为 text_block ⾥的 query 部分添加css_class,html_tag,⽽max_length 为最终返回长度,相当于 cut ,我看了⼀下此标签实现源码,默认的html_tag 值为 span ,css_class 值为 highlighted,max_length 值为 200,然后就可以通过CSS来添加效果。如默认时:
span.highlighted {
color: red;
}
Example:
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论