新闻搜索

一、搜索功能分析

  思考:如果我们要做一个通过关键词搜索文章的功能,需要搜索哪些字段,以及使用什么技术方案?

搜索字段:

  1,字段

  2,内容

  3,作者

技术方案:

  1,mysql的模糊查询%like%

    1,优点:实现起来简单

    2,缺点:数据量比较大的情况下,查询效率极低

  2,全文检索引擎

    1,优点:专业的全文检索引擎,效率高

    2,缺点:实现起来比较复杂

选择使用全文检索引擎,自行实现django框架和全文检索引擎的代码比较麻烦,选用django的

第三方包djangohaystack。它支持多钟全文检索引擎,本项目选择最流行的全文检索引擎之一

elasticsearch

二、elasticsearch介绍

  elasticsearch原理:http://developer.51cto.com/art/201904/594615.htm

三、docker介绍

  1.docker介绍与安装

    ~介绍

      1,什么是docker?

        ~简化创建,部署,运行应用程序的一个工具

        ~打包应用程序所需的库和依赖环境

        ~精简的虚拟机

  2.为什么使用docher?

    流行、方便、强大

  3.docker  vs 虚拟机

    体积更小、运行更快、集成扩展更好

  4.docker架构

    ~架构

      ~客户端

      ~守护进程

      ~仓库 

    ~docker对象

      ~镜像  精简linux  

      ~容器

      ~服务

    ~docker Hub

    安装

    官方安装文档:https://www.docker.com/

    lsb_release -a   #查看系统信息 

五、新闻搜索功能实现

  1,业务流程分析

    判断是否传递查询参数q

    如果没有传递q,则直接返回热门新闻数据

    如果没有传递,则返回查询结果

  2,接口设计

    1.接口说明:

    类目          说明

    请求方法        GET

    url定义         /news/search/

    参数格式        查询参数

    2.参数说明:

    参数名      类型    是否必须    描述

    q        字符串     否     查询的关键字

    page      整数      否      页码

    3.返回结果:

    搜索页面html

1.创建haystack数据模型

news/search_indexes 文件代码

  


from haystack import indexes
from .models import News


class NewsIndex(indexes.SearchIndex, indexes.Indexable):
"""
这个模型的作用类似于django的模型,它告诉haystack哪些数据会被
放到查询返回的模型对象中,以及通过哪些字段进行索引和查询

"""
text = indexes.CharField(document=True, use_template=True)
id = indexes.CharField(model_attr='id')
title = indexes.CharField(model_attr='title')
digest = indexes.CharField(model_attr='digest')
content = indexes.CharField(model_attr='content')
image_url = indexes.CharField(model_attr='image_url')

def get_model(self):
"""
返回建立索引的模型
:return:
"""
return News

def index_queryset(self, using=None):
"""
返回要建立索引的数据查询集
:param using:
:return:
"""
return self.get_model().objects.filter(is_delete=False)


2,创建索引数据模版
  templates/search/indexes/news/news_text.txt 文件
  
  {{ object.title }}
  {{ object.digest }}
  {{ object.content }}
  {{ object.author.username }}

3,创建索引

虚拟机进入项目根目录

运行命令:python manage.py -h

python manage.py rebuild_index

 代码:

news/templatetags/news_template_filters.py 

from django import template

register = template.Library()


@register.filter()
def page_bar(page):
page_list = []
if page.number != 1:
page_list.append(1)
if page.number - 3 > 1:
page_list.append('...')
if page.number - 2 > 1:
page_list.append(page.number - 2)
if page.number - 1 > 1:
page_list.append(page.number -1)

page_list.append(page.number)

if page.paginator.num_pages > page.number + 1:
page_list.append(page.number + 1)
if page.paginator.num_pages > page.number + 2:
page_list.append(page.number + 2)
if page.paginator.num_pages > page.number + 3:
page_list.append('...')
if page.paginator.num_pages != page.number:
page_list.append(page.paginator.num_pages)

return page_list

apps/news/views.py 代码
class NewsSearchView(SearchView):
"""
新闻搜索视图
url: /news/search/
"""
# 配置搜索模板文件
template_name = 'news/search.html'

def get(self, request, *args, **kwargs):
# 1. 获取查询参数
query = request.GET.get('q')
if not query:
# 2. 如果没有查询数
# 返回热门新闻
hot_news = HotNews.objects.select_related('news__tag').only('news__title', 'news__image_url', 'news_id', 'news__tag__name').filter(is_delete=False).order_by('priority', '-news__clicks')
# 分页
paginator = Paginator(hot_news, settings.HAYSTACK_SEARCH_RESULTS_PER_PAGE)

try:
page = paginator.get_page(int(request.GET.get('page')))
except Exception as e:
page = paginator.get_page(1)

return render(request, self.template_name, context={
'page': page,
'query': query
})
else:
# 3. 如果有怎么办
return super().get(request, *args, **kwargs)

def get_context_data(self, *args, **kwargs):
"""
在context中添加变量page
:param args:
:param kwargs:
:return:
"""
context = super().get_context_data(*args, **kwargs)
if context['page_obj']:
context['page'] = context['page_obj']

return context

          

猜你喜欢

转载自www.cnblogs.com/wdty/p/11385965.html
今日推荐