PyxYuYu/MyBlog

Django学习记录(二十四):Django by example -- Blog(二十)

PyxYuYu opened this issue · 0 comments

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 中的 Reloadschema.xml 就会重新生效
      • 但是利用 Haystack 生成的 schema.xml 有很多类已经在 Solr 6 中被移除了,所以 Reload 的时候会报错
        • 第一个错误 : "sint": Error loading class 'solr.SortableIntField'
          • Solr 5 中,ByteFieldShortField 都被删除了,所以在 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 ,就可以实现新增内容的搜索了