• 【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,文章的更新编辑以此链接为准。欢迎关注源站文章!

  • 相关阅读:
    Vue中父子组件的通讯
    字符串svg代码转 base64 url
    Vue 中封装 websocket
    vue中使用Echarts,销毁原有的图表进行重新赋值
    Vue中常用表格(增删改查)
    刷新组件
    hdu1272小希的迷宫(并查集+判环)
    九余数定理
    Runtime Error可能的情况
    hdu2035 人见人爱A^B题解
  • 原文地址:https://www.cnblogs.com/djcoder/p/10863993.html
Copyright © 2020-2023  润新知