注意:系统环境为Ubuntu18

一、docker安装

  0:如果之前有安装过docker使用以下命令卸载:

sudo apt-get remove docker docker-engine docker.io containerd runc

  docker安装官网参考:

https://docs.docker.com/install/linux/docker-ce/ubuntu/

  1:首先更新apt

sudo apt-get update

  2:添加证书安装包以允许apt通过HTTPS:

sudo apt-get install \
apt-transport-https \
ca-certificates \
curl \
gnupg-agent \
software-properties-common

  3:添加docker官方密钥

curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -

  4:添加仓库

sudo add-apt-repository \
"deb [arch=amd64] https://download.docker.com/linux/ubuntu \
$(lsb_release -cs) \
stable"

  5:安装docker ce

sudo apt-get install docker-ce docker-ce-cli containerd.io

  6:测试

sudo docker run hello-world

  7:添加当前系统用户到docker用户组

sudo usermod -aG docker 用户名  

docker 拓展命令:

  docker images :查看所有启动成功的镜像

  docker ps -a :查看所有

  docker logs 容器id :查看容器日志

  docker 如果启动容器失败,就先删除容器,删除目录,再次执行安装。

二、使用docker安装Elasticsearch

1:获取镜像

docker image pull delron/elasticsearch-ik:2.4.6-1.0  

 如果pull拉取很慢可以从我的百度云中下载,然后传到Linux系统中然后使用docker命令导入

链接:https://pan.baidu.com/s/1zXBR_uHSFxK5xNxklGV1pQ
提取码:96iw

docker load -i elasticsearch-ik-2.4.6_docker.tar

 查看本地仓库是否有这个镜像

docker images

docker image ls

  将下载的elasticsearch.zip上传到Linux系统中的家目录,然后解压。在目录中的elasticsearch/config/elasticsearch.yml第54行更改IP地址为0.0.0.0,端口改为8002,默认为9002

  解压命令:

unzip elasticsearch.zip

 

2:创建docker容器并运行

 根据拉取到本地的镜像创建容器,需要将elasticsearch/config配置文件所在目录修改为你自己的路径

docker run -dti --network=host --name=elasticsearch -v /home/上面上传后解压出来的文件路径地址/elasticsearch/config:/usr/share/eleaticsearh/config delron/elasticsearch-ik:2.4.6-1.0

  查看是否创建成功,如果STATUS为Up则创建成功

docker container ls -a 或 docker ps -a

  

测试 curl 127.0.0.1:8002

3:进入项目的虚拟环境中,安装以下包

pip install django-haystack
pip install elasticsearch==2.4.1

  

4:在django项目配置,在settings.py文件中加入下面配置。

4-1:在INSTALLED_APPS节点中注册haystack

INSTALLED_APPS = [
...
'haystack',
...
]

4-2:加入配置

# 建立连接
ELASTICSEARCH_DSL = {
  'default':{
    'host':'127.0.0.1:8002'  
  },
}
# 配置Haystack
HAYSTACK_CONNECTIONS = {
'default': {
'ENGINE': 'haystack.backends.elasticsearch_backend.ElasticsearchSearchEngine',
'URL': 'http://127.0.0.1:8002/', # 此处为elasticsearch运行的服务器ip地址,端口号固定为9200
'INDEX_NAME': 'mysite', # 指定elasticsearch建立的索引库的名称
},
} # 当添加、修改、删除数据时,自动生成索引,当数据库改变时候,会自动更新索引
HAYSTACK_SIGNAL_PROCESSOR = 'haystack.signals.RealtimeSignalProcessor' 
# 每页显示多少条数据
HAYSTACK_SEARCH_RESULTS_PER_PAGE = 20

5:建立索引

在需要创建索引的实体中创建search_indexes.py(文件名固定写法)

  

5-1:search_indexes.py文件内容如下:

from haystack import indexes
from .models import News # 导入模型类 # 建索引类
# 模型名称+Index(固定的)
class NewsIndex(indexes.SearchIndex, indexes.Indexable):
'''
News索引数据库模型
'''
# 这个主要是使用5-2来建立索引
text = indexes.CharField(document=True, use_template=True)
# 以下是为了在使用时 news.id 如果没有写就需要news.object.id
id = indexes.IntegerField(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 News def index_queryset(self, using=None):
'''
返回要建立索引的数据查询集
:param using:
:return:
''' return set.get_model().objects.filter(is_delete=False, tag_id=1)
# return set.get_model().objects.filter(is_delete=False,tag_id=[1,2,3,4,5])

  

5-2:创建模板

# 需要在templates文件夹中创建一个search/indexes/app名称/模型名称小写_text.txt文件(固定结构)

  

news_text.txt内容为:需要建立的索引

6:生成索引

通过xshell进入项目进入虚拟环境执行

python manage.py rebuild_index

  

7: 分页搜索接口/方法

7-1

from haystack.views import SearchView as _SearchView
from .models import News # 导入模型类
from .models import HotNews
from mysite import setttings
from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
from django.shortcuts import render
from django.views import View class SearchView(_SearchView):
# 模板文件
template = 'news/search.html' # 重写响应方式,如果请求参数为空,返回模型News的热门新闻数据,否则根据参数q搜索相关数据
def create_response(self):
kw = self.request.GET.get('q', '')
if not kw:
show_all = True
hot_news = HotNews.objects.select_related(
'News'
).only(
'news__title',
'news__image_url',
'news__id'
).filter(
is_delete=False
).order_by(
'priority',
'-news__clicks'
)
paginator = Paginator(hot_news, setttings.HAYSTACK_SEARCH_RESULTS_PER_PAGE)
try:
page = paginator.page(int(self.request.GET.get('page', 1)))
except PageNotAnInteger:
# 如果参数page的数据类型不是整数,则返回第一页数据
page = paginator.page(1)
except EmptyPage:
# 用户访问的页数大于实际的页数,则返回最后一页的数据
page = paginator.page(paginator.num_pages)
return render(self.request, self.template, locals())
else:
show_all = False
qs = super(SearchView, self).create_response()
return qs

7-2:在app中的urls中设置url

path('search/',view.SearchView(),name='search')

7-3:前端部分代码

         <div class="content">
<!-- search-list start -->
{% if not show_all %}
<div class="search-result-list">
<h2 class="search-result-title">
搜索结果 <span style="font-weight: 700;color: #ff6620;">{{ paginator.num_pages }}</span>页
</h2>
<ul class="news-list">
{% for one_news in page.object_list %}
<li class="news-item clearfix">
<a href="{% url 'news:detail' one_news.id %}" class="news-thumbnail"
target="_blank">
<img src="{{ one_news.object.image_url }}">
</a>
<div class="news-content">
<h4 class="news-title">
<a href="{% url 'news:detail' one_news.id %}">
{% highlight one_news.title with query %}
</a>
</h4>
<p class="news-details">{% highlight one_news.digest with query %}</p>
<div class="news-other">
<span class="news-type">{{ one_news.object.tag.name }}</span>
<span class="news-time">{{ one_news.object.update_time }}</span>
<span
class="news-author">{% highlight one_news.object.author.username with query %} </span>
</div>
</div>
</li>
{% endfor %} </ul>
</div> {% else %} <div class="news-contain">
<div class="hot-recommend-list">
<h2 class="hot-recommend-title">热门推荐</h2>
<ul class="news-list"> {% for one_hotnews in page.object_list %} <li class="news-item clearfix">
<a href="#" class="news-thumbnail">
<img src="{{ one_hotnews.news.image_url }}">
</a>
<div class="news-content">
<h4 class="news-title">
<a href="{% url 'news:detail' one_hotnews.news.id %}">{{ one_hotnews.news.title }}</a>
</h4>
<p class="news-details">{{ one_hotnews.news.digest }}</p>
<div class="news-other">
<span class="news-type">{{ one_hotnews.news.tag.name }}</span>
<span class="news-time">{{ one_hotnews.update_time }}</span>
<span class="news-author">{{ one_hotnews.news.author.username }}</span>
</div>
</div>
</li> {% endfor %} </ul>
</div>
</div> {% endif %} <!-- search-list end -->
<!-- news-contain start --> {# 分页导航 #}
<div class="page-box" id="pages">
<div class="pagebar" id="pageBar">
<a class="a1">{{ page.paginator.count }}条</a>
{# 上一页的URL地址 #}
{% if page.has_previous %}
{% if query %}
<a href="{% url 'news:search' %}?q={{ query }}&page={{ page.previous_page_number }}"
class="prev">上一页</a>
{% else %}
<a href="{% url 'news:search' %}?page={{ page.previous_page_number }}" class="prev">上一页</a>
{% endif %}
{% endif %}
{# 列出所有的URL地址 #}
{% for num in page.paginator.page_range|slice:":10" %}
{% if num == page.number %}
<span class="sel">{{ page.number }}</span>
{% else %}
{% if query %}
<a href="{% url 'news:search' %}?q={{ query }}&page={{ num }}"
target="_self">{{ num }}</a>
{% else %}
<a href="{% url 'news:search' %}?page={{ num }}" target="_self">{{ num }}</a>
{% endif %}
{% endif %}
{% endfor %} {# 如果页数大于10,则打两点 #}
{% if page.paginator.num_pages > 10 %}
.. {% if query %}
<a href="{% url 'news:search' %}?q={{ query }}&page={{ page.paginator.num_pages }}"
target="_self">{{ page.paginator.num_pages }}</a>
{% else %}
<a href="{% url 'news:search' %}?page={{ page.paginator.num_pages }}"
target="_self">{{ page.paginator.num_pages }}</a>
{% endif %} {% endif %} {# 下一页的URL地址 #}
{% if page.has_next %}
{% if query %}
<a href="{% url 'news:search' %}?q={{ query }}&page={{ page.next_page_number }}"
class="next">下一页</a>
{% else %}
<a href="{% url 'news:search' %}?page={{ page.next_page_number }}"
class="next">下一页</a>
{% endif %}
{% endif %}
</div>
</div> <!-- news-contain end -->
</div>

  

7-4:高亮及分页样式

/* === current index start === */
#pages {
padding: 32px 0 10px;
} .page-box {
text-align: center;
/*font-size: 14px;*/
} #pages a.prev, a.next {
width: 56px;
padding: 0
} #pages a {
display: inline-block;
height: 26px;
line-height: 26px;
background: #fff;
border: 1px solid #e3e3e3;
text-align: center;
color: #333;
padding: 0 10px
} #pages .sel {
display: inline-block;
height: 26px;
line-height: 26px;
background: #0093E9;
border: 1px solid #0093E9;
color: #fff;
text-align: center;
padding: 0 10px
} .highlighted{
color:coral;
mso-ansi-font-weight: bold;
}
/* === current index end === */

  

8:效果图

python-django框架中使用docker和elasticsearch配合实现搜索功能的更多相关文章

  1. Python的Django框架中forms表单类的使用方法详解

    用户表单是Web端的一项基本功能,大而全的Django框架中自然带有现成的基础form对象,本文就Python的Django框架中forms表单类的使用方法详解. Form表单的功能 自动生成HTML ...

  2. Python的Django框架中的Cookie相关处理

    Python的Django框架中的Cookie相关处理 浏览器的开发人员在非常早的时候就已经意识到. HTTP's 的无状态会对Web开发人员带来非常大的问题,于是(cookies)应运而生. coo ...

  3. Python的Django框架中的Context使用

    Python的Django框架中的Context使用 近期整理些Python方面的知识,一旦你创建一个 Template 对象,你能够用 context 来传递数据给它. 一个context是一系列变 ...

  4. Python中的Django框架中prefetch_related()函数对数据库查询的优化

    实例的背景说明 假定一个个人信息系统,需要记录系统中各个人的故乡.居住地.以及到过的城市.数据库设计如下: Models.py 内容如下: ? 1 2 3 4 5 6 7 8 9 10 11 12 1 ...

  5. Python的Django框架中的URL配置与松耦合

    Python的Django框架中的URL配置与松耦合 用 python 处理一个文本时,想要删除其中中某一行,常规的思路是先把文件读入内存,在内存中修改后再写入源文件. 但如果要处理一个很大的文本,比 ...

  6. Django框架中的Context使用

    Django框架中的Context使用 2017年11月09日 20:01:09 aweilark 阅读数:1113   转载自:http://www.aichengxu.com/python/606 ...

  7. 分布式队列celery 异步----Django框架中的使用

    仅仅是个人学习的过程,发现有问题欢迎留言 一.celery 介绍 celery是一种功能完备的即插即用的任务对列 celery适用异步处理问题,比如上传邮件.上传文件.图像处理等比较耗时的事情 异步执 ...

  8. [Python] Django框架入门

    说明:Django框架入门 当前项目环境:python3.5.django-1.11 项目名:test1 应用名:booktest 命令可简写为:python manager.py xxx => ...

  9. Django框架中logging的使用

    Django框架中logging的使用 日志是我们在项目开发中必不可少的一个环节,Python中内置的logging已经足够优秀到可以直接在项目中使用. 本文介绍了如何在DJango项目中配置日志. ...

随机推荐

  1. SpringBoot:关于默认连接池Hikari的源码剖析

    1.起因 因为这两天在给公司的一个项目升级SpringBoot版本,遇到了一些坑,升级项目版本:SpringBoot1.5.x到SpringBoot2.0.x 今天早上双库操作遇到一个问题:jdbcU ...

  2. 关于python的深拷贝和浅拷贝

    写类函数的时候出了一个错,原代码写在这里: def Update(self, wm, vm, ts, pos, vn, att): # 上一时刻位置,速度 pos_pre = pos self.pos ...

  3. ubuntu之路——day17.1 卷积操作的意义、边缘检测的示例、filter与padding的关系、卷积步长

    感谢吴恩达老师的公开课,以下图片均来自于吴恩达老师的公开课课件 为什么要进行卷积操作? 我们通过前几天的实验已经做了64*64大小的猫图片的识别. 在普通的神经网络上我们在输入层上输入的数据X的维数为 ...

  4. idea在docker环境,调试spring boot程序

    允许docker被远程访问 见:https://www.cnblogs.com/wintersoft/p/10921396.html 教程见:https://spring.io/guides/gs/s ...

  5. oracle 19c jdbc之Reactive Streams Ingestion (RSI) Library

    19c jdbc新特性 https://blogs.oracle.com/dev2dev/whats-new-in-193-and-183-jdbc-and-ucp jdbc实现直接路径加载 http ...

  6. SDN实验---Mininet的相关命令(待补充完善)

    一:补充 (一)推文 openvswitch的原理和常用命令 https://blog.csdn.net/ten_sory/article/details/79593554 (二)回顾:sudo mn ...

  7. iOS开发应该知道的7个编程概念

    对流行工具(如Xcode)和编程概念(如视图控制器)的高级讨论,这些对iOS开发本身很有用. 1. Xcode Xcode是iOS应用开发社区所见过的最通用的IDE.由于集成开发环境来自Apple,它 ...

  8. python提取mysql中指定列参数,并循环打印

    试验环境: Python 3.7.0 Mysql 5.0 实验目的: 使用python将数据库中指定的列中的数值取出来,并循环遍历,用以当成参数传递给需要它的方法. 本次实验取的是para列的数据 实 ...

  9. 论文阅读:FaceBoxes: A CPU Real-time Face Detector with High Accuracy

    文章: <FaceBoxes: A CPU Real-time Face Detector with High Accuracy> Introduction 2个挑战: 1)在杂乱背景下人 ...

  10. 【linux学习笔记六】压缩 解压缩命令

    所有的压缩文件一定要写压缩格式的扩展名 .zip格式压缩 #压缩文件 zip 压缩文件名 源文件 #压缩目录 zip -r 压缩文件名 源目录 #解压缩 unzip 压缩文件 .gz格式压缩 #压缩为 ...