Django学习记录(二十四):Django by example -- Blog(二十)
PyxYuYu opened this issue · 0 comments
PyxYuYu commented
Learn wisdom by the follies of others.
0x01 Django
- Build a Blog Application
- 昨天创建好
Solr
的搜索索引后,需要根据搜索索引建立一个schema.xml
来替代之前的空schema.xml
python manage.py build_solr_schema
- 复制整个输出,保存到
apache-tomcat-8.0.39\webapps\solr\solr_home\blog\conf\schema.xml
xml
中会有搜索索引的指定字段
<field name="text" type="text_en" indexed="true" stored="true" multiValued="false" /> <field name="publish" type="date" indexed="true" stored="true" multiValued="false" />
- 打开
http://localhost:8888/solr/index.html#/~cores/blog
,点击blog core
中的Reload
,schema.xml
就会重新生效 - 但是利用
Haystack
生成的schema.xml
有很多类已经在Solr 6
中被移除了,所以Reload
的时候会报错- 第一个错误 :
"sint": Error loading class 'solr.SortableIntField'
- 在
Solr 5
中,ByteField
和ShortField
都被删除了,所以在schema.xml
中,以下旧配置都需要删除
<fieldType name="sint" class="solr.SortableIntField" sortMissingLast="true" omitNorms="true"/> <fieldType name="slong" class="solr.SortableLongField" sortMissingLast="true" omitNorms="true"/> <fieldType name="sfloat" class="solr.SortableFloatField" sortMissingLast="true" omitNorms="true"/> <fieldType name="sdouble" class="solr.SortableDoubleField" sortMissingLast="true" omitNorms="true"/>
- 在
- 继续
Reload
又会报错 :
Error instantiating class: 'org.apache.lucene.analysis.core.StopFilterFactory'
- 删除
schema.xml
中所有的enablePositionIncrements="true"
- 删除
- 继续
Reload
继续报错 :
Error instantiating class:'org.apache.lucene.analysis.ngram.EdgeNGramFilterFactory'
- 删除
schema.xml
中所有的side="front"
- 删除
- 这样
Reload
就可以重新成功加载了
- 第一个错误 :
Indexing data
- 重新索引
posts
,将数据加载到Solr
中
python manage.py rebuild_index
cmd
会提示询问是否要删除所有之前的索引内容并重建新的,选y
之后会建立posts
索引- 注意:
python manage.py update_index
不会移除之前的索引,所以可以设置一个定时任务,自动更新后面的索引
- 重新索引
Creating a search view
- 创建一个自定义的搜索视图
- 先添加一个搜索
form
,编辑blog/forms.py
,增加
class SearchForm(forms.Form): query = forms.CharField()
query
字段用于引入搜索的选项- 编辑
views.py
,添加视图post_search
from .forms import EmailPostForm, CommentForm, SearchForm from haystack.query import SearchQuerySet def post_search(request): form = SearchForm() if 'query' in request.GET: form = SearchForm(request.GET) if form.is_valid(): cd = form.cleaned_data results = SearchQuertSet().models(Post).filter(content=cd['query']).load_all() # 计算所有结果 total_results = results.count() else: cd = {} results = {} total_results = {} return render(request, 'blog/post/search.html', {'form': form, 'cd': cd, 'results': results, 'total_results': total_results})
post_search
视图中,form
从之前创建的SearchForm
获得,我们用GET
方法提交form
后,返回的URL
中就会存在query
参数,所以用if
来判断是否提交了,如果提交的话,则获取提交的数据,判断是否有效,如果有效,则用SearchQuerySet
来执行搜索内容load_all()
函数会从数据库中导入所有有关联的Post
对象- 最后需要一个搜索模板,显示
form
和搜索结果 - 创建
templates/blog/post/search.html
{% extends "blog/base.html" %} {% block title %}Search{% endblock %} {% block content %} {% if "query" in request.GET %} <h1>Posts containing "{{ cd.query }}"</h1> <h3>Fount {{ total_results }} result{{total_results|pluralize}}</h3> {% for result in results %} {% with post=result.object %} <h4><a href="{{ post.get_absolute_url }}">{{ post.title }}</a></h4> {{ post.body|truncatewords:5 }} {% endwith %} {% empty %} <p>There are no results for your query.</p> {% endfor %} <p><a href="{% url "blog:post_search" %}">Search again</a></p> {% else %} <h1>Search for posts</h1> <form action="." method="get"> {{ form.as_p }} <input type="submit" value="Search"> </form> {% endif %} {% endblock %}
- 上面的模板区分开了是否提交,没有提交的话,则显示
form
和按钮,提交的话,显示查询被执行,显示结果,我们用result.object
来获取结果中的Post
对象 - 为视图添加
URL pattern
,编辑blog/urls.py
url(r'^search/$', views.post_search, name='post_search'),
- 这样
Django
的全文搜索就实现了,如果新增内容,需要先更新索引pyton manage.py update_index
,就可以实现新增内容的搜索了
- 昨天创建好