注意:系統環境爲Ubuntu18css
1、docker安裝html
0:若是以前有安裝過docker使用如下命令卸載:前端
sudo apt-get remove docker docker-engine docker.io containerd runc
docker安裝官網參考:python
https://docs.docker.com/install/linux/docker-ce/ubuntu/linux
1:首先更新aptdocker
sudo apt-get update
2:添加證書安裝包以容許apt經過HTTPS:shell
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:添加倉庫django
sudo add-apt-repository \ "deb [arch=amd64] https://download.docker.com/linux/ubuntu \ $(lsb_release -cs) \ stable"
5:安裝docker ceubuntu
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 若是啓動容器失敗,就先刪除容器,刪除目錄,再次執行安裝。
2、使用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:效果圖