【13】网站搭建:全文搜索

一、前言

  关于全文搜索的部分,主要是利用了haystack,whoosh和jieba这三个包,而且必须安装,否则以下内容无效。详细的说法已经在之前Django框架的学习内容中总结过了:Django 框架15: 全文搜索

  这次继续学习全文搜索的内容主要是因为在之前的内容中,缺少了自定义全文搜索部分。因为在后来的开发中,我发现搜索页的结果只有在blog_text.txt中出现过的字段名。如果我想继续如博客列表那样显示出榜单排行就无法实现了,因为search.html模板页面不会经过自定义的views,所以就必须采用某种办法可以实现自定义某种context参数传递到search.html模板页面中。

二、使用方法

  幸运的是,haystack的views提供了extra_context这种接口,通过继承SearchView类,就可以重写该方法。

def extra_context(self):
    """
    Allows the addition of more context variables as needed.

    Must return a dictionary.
    """
    return {}

  首先,编写一个MySeachView类,让它继承SearchView类。

from haystack.views import SearchView
from read_statistics.utils import get_random_recomment, get_new_recommend_post, get_all_read_posts
from django.contrib.contenttypes.fields import ContentType
from .models import Post
from django.core.paginator import *   # 导入分页功能
from blogproject.settings import *

class MySeachView(SearchView):
    """
    作用:自定义的search视图
    SearchView:继承SearchView类
    """
    def extra_context(self):  # 重载extra_context来添加额外的context内容
        """
        添加自定义的context参数,传递到search.html视图
        :return: 自定义的context参数
        """
        context = super(MySeachView, self).extra_context()

        # 这里的EACH_RAGE_BLOG_NUMBER等于10,已经当成常量写进了seetings里
        paginator = Paginator(self.results, EACH_RAGE_BLOG_NUMBER)

        # 采用get方式获取用户访问的页码,如果获取不到,默认为第一页
        page_num = self.request.GET.get('page', 1)

        # 因为用户输入不一定是数字,所以需要用int(page_num),而django里的get_page会自动识别用户输入以及页码范围
        # 注意这里的page_of_list是一个paginator对象
        page_of_list = paginator.page(int(page_num))

        # 获取当前页码
        current_page_num = page_of_list.number

        # page_range = [current_page_num - 2, current_page_num - 1,
        # current_page_num, current_page_num + 1, current_page_num + 2]

        # 获取当前页码前后各两页的页码范围
        # 需要注意判断的是:如果当前页是第一页,那么前两页不能是0,也不能是-1,所以要使用内置max函数来与1比较最大值
        # 同理:如果当前页已经是最后一页,那么就不能取到当前页+2的页码了,所以要使用内置min函数来与最大页码比较最小值
        page_range = list(range(max(current_page_num - 2, 1), current_page_num)) + 
                     list(range(current_page_num, min(current_page_num + 2, paginator.num_pages) + 1))

        # 加上省略页码标记
        # paginator.num_pages表示一共有多少页码
        if page_range[0] - 1 >= 2:
            page_range.insert(0, '...')
        if paginator.num_pages - page_range[-1] >= 2:
            page_range.append('...')

        # 加上首页尾页
        # paginator.num_pages表示一共有多少页码
        if page_range[0] != 1:
            page_range.insert(0, 1)
        if page_range[-1] != paginator.num_pages:
            page_range.append(paginator.num_pages)

        # 随机推荐的15篇博客
        random_recommend = get_random_recomment()

        # 最新推荐的15篇博客
        post_content_type = ContentType.objects.get_for_model(Post)
        new_recommend = get_new_recommend_post(post_content_type)

        # 阅读量总榜博客榜单
        all_hot_posts = get_all_read_posts()
        context = {
                'page_range': page_range,
                'random_recommend': random_recommend,
                'new_recommend': new_recommend,
                'all_hot_posts': all_hot_posts,
            }
        return context

  如上可以看到,我已经新加了一些参数放到了context里面,然后把该类添加到项目的url中。

url(r'^search/', MySeachView(), name='haystack_search'),

  最后修改search.html模板就可以完全实现自定义的搜索页的视图功能了。

  原文出处:https://jzfblog.com/detail/96,文章的更新编辑以此链接为准。欢迎关注源站文章!

原文地址:https://www.cnblogs.com/djcoder/p/10863993.html