[django項目] 利用elasticsearch實現搜索功能
新聞搜索
I. 搜索功能分析
本節我們來完成新聞搜索功能, 首先讓我們來思考一下,要做一個通過關鍵詞搜索文章的功能,需要搜索哪些字段,以及使用什麼技術方案呢?
既然我們是準備做新聞博客網站, 那我們就可以拿同類型網站的做一下對比, 例如CSDN, 簡書, 博客園等, 這些常見的博客網站其主要覆蓋的搜索字段有:
- 標題
- 內容
- 作者
實現這些字段檢索的技術方案有以下兩種:
- mysql的模糊查詢
%like%
- 優點:實現起來簡單
- 缺點:數據量比較大的情況下,查詢效率極低
- 全文檢索引擎
- 優點:專業的全文檢索引擎,效率高
- 缺點:實現起來比較複雜
本項目選擇使用過全文檢索引擎。自行實現django框架和全文檢索引擎的代碼比較麻煩,抱着不重複造輪子的原則,這裏我們選用django的第三方包djangohaystack
。它支持多種全文檢索引擎,本項目選擇最流行的全文檢索引擎之一elasticsearch
。
II. elasticsearch介紹
elasticsearch 原理:http://developer.51cto.com/art/201904/594615.htm
工作原理示意圖
- 首先來看圖中, 用戶將
全文搜索
的請求發送至django, 即輸入搜索內容 - 全文搜索需要
分詞
和模糊查詢
, 這些操作在mysql中也可以使用, 但如果遇到數據量大的項目, 效率會很低, 因此, 就需要藉助搜索引擎elasticsearch
- 要實現查詢, 那麼我們的django需要連接
mysql
和elasticsearch
:- 連接mysql使用的是
mysqlclient
- 連接elasticsearch使用的是
django-haystack
, 以及python的es驅動
- 連接mysql使用的是
- elasticsearch會去到mysql中
獲取數據
, 然後進行索引
, 並儲存到它自己那裏 - 然後django就會利用haystack到elasticsearch中查詢想要的數據, 即執行搜索
- es查詢到後返回給haystack(haystack是屬於django項目中的一個從外部引入的app)
- haystack會返回給django框架, 然後django再展示給用戶看, 即展示搜索結果
III. docker介紹與安裝
1>docker介紹
1.1>什麼是docker?
- 簡化創建,部署,運行應用程序的一個工具
- 打包應用程序所需的庫和依賴環境
- 精簡的虛擬機
1.2>爲什麼使用docker?
流行,方便,強大
1.3>docker vs 虛擬機
1.4>docker架構
-
架構
- 客戶端
- 守護進程
- 倉庫
-
docker 對象
- 鏡像 精簡的linux
- 容器
- 服務
-
docker Hub
-
安裝
lsb_release -a # 查看系統信息 uname -a # 查看位數
- 1
- 2
2>ubuntu下安裝
如果是第一次安裝,你需要先添加docker的源然後再安裝
2.1>添加阿里雲源
- 百度搜索"阿里雲源"
- 選擇Ubuntu然後複製源鏈接
- 桌面創建一個txt文件, 重命名爲
sources.list
- 使用NotePad++或是pycharm打開, 粘貼源鏈接, 保存
- 粘貼文件到linux的家目錄
cd /etc/apt/
- 備份原有的
sources.list
, 使用命令:sudo cp sources.list sources.dbk.list
- 然後
sudo rm sources.list
, 再將你剛纔創建的sources.list
拷貝到/etc/apt/
- 運行命令:
sudo apt-get update
, 刷新源 - 如果有問題則
sudo apt-get upgrade
更新系統, 然後再刷新源
2.2>安裝證書
$ sudo apt-get install apt-transport-https ca-certificates curl gnupg-agent software-properties-common
- 1
2.3>添加官方GPGkey
$ curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
- 1
2.4>添加docker源
$ sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable"
- 1
3>安裝 docker ce
3.1>更新包索引
$ sudo apt-get update
- 1
3.2>安裝docker
(這個可能會很久)
$ sudo apt-get install docker-ce
- 1
3.3>檢測是否安裝成功
$ sudo docker run hello-world
- 1
安裝成功會出現如下輸出:
Hello from Docker!
This message shows that your installation appears to be working correctly.
To generate this message, Docker took the following steps:
- The Docker client contacted the Docker daemon.
- The Docker daemon pulled the “hello-world” image from the Docker Hub.
(amd64) - The Docker daemon created a new container from that image which runs the
executable that produces the output you are currently reading. - The Docker daemon streamed that output to the Docker client, which sent it
to your terminal.
To try something more ambitious, you can run an Ubuntu container with:
$ docker run -it ubuntu bash
Share images, automate workflows, and more with a free Docker ID:
https://hub.docker.com/
For more examples and ideas, visit:
https://docs.docker.com/get-started/
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
爲了方便使用,不用sudo就可以運行docker命令,安裝好docker後再命令行輸入如下命令:
$ sudo usermod -aG docker $USER
- 1
運行正常後,重新連接即可。
IIII. 搜索功能環境搭建
1>在docker中安裝elasticsearch
1.1>獲取鏡像
# 注意:因爲haystack目前支持的elasticsearch版本爲 1.x和2.x
# 所以這裏選擇2.4.6
$ docker pull elasticsearch:2.4.6
- 1
- 2
- 3
1.2>安裝中文分詞插件
可以創建容器之後再安裝插件,爲了後面部署方便,我們創建鏡像。elasticsearch的中文分詞插件是elasticsearch-ik
,國人開發,github地址。
根據文檔介紹,2.4.6版本對應的ik是1.10.16
因爲直接使用elasticsearch的plugin命令安裝會報錯,所以通過下載後解壓到相應文件夾的方式安裝。
)]
a.下載es-ik後,將其解壓到名爲ik的文件夾
~$ unzip elasticsearch-analysis-ik-1.10.6.zip -d ./ik
- 1
b.在ik所在文件下創建名爲Dockerfile
的文件,內容如下
# dockerfile
FROM elasticsearch:2.4.6
MAINTAINER Fisher "[email protected]"
ADD ./ik/ /usr/share/elasticsearch/plugins/ik/
- 1
- 2
- 3
- 4
然後運行命令
~$ sudo docker build -t xinlan/els-ik:2.4.6 .
- 1
如果出現下面的錯誤是因爲沒有帶sudo
~$ docker build -t xinlan/els-ik:2.4.6 .
error checking context: 'no permission to read from '/home/wcf/.viminfo''.
- 1
- 2
運行成功後,會在你的docker中創建一個新的鏡像
~$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
xinlan/els-ik 2.4.6 ecf93deefe2b 26 minutes ago 489MB
elasticsearch 2.4.6 5e9d896dc62c 10 months ago 479MB
- 1
- 2
- 3
- 4
如果上面的步驟搞不定請直接下載如下鏡像
$ sudo docker image pull wcfdehao/els-ik:2.4.6
- 1
2>創建容器
利用上面創建好的鏡像創建一個容器。爲了能夠進行設置elasticsearch,通過卷掛載的方式創建容器。
將提供給大家的es配置文件elasticsearch.zip
拷貝到家目錄下,然後解壓
# 在xshell中使用rz命令將elasticsearch.zip文件傳到虛擬機的家目錄中
#然後在家目錄中解壓
~$ unzip elasticsearch.zip
- 1
- 2
- 3
然後運行下面的命令創建容器
# 根據上面創建的鏡像創建容器,需要將/home/wcf/elasticsearch/config配置文件路徑修改爲你自己的路徑
~$ docker run -dti --network=host --name es-ik -v /home/pyvip/elasticsearch/config:/usr/share/elasticsearch/config wcfdehao/els-ik:2.4.6
# 查看當前運行的容器
~$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
61c42c36a8f2 xinlan/els-ik:2.4.6 “/docker-entrypoint.…” 29 minutes ago Up 28 minutes es-ik
- 1
- 2
- 3
- 4
- 5
- 6
- 7
你也可以在創建時攜帶restart參數, 讓容器可以自啓, 具體可以參考本文的後半段
最後運行curl命令檢測es是否正常
~$ curl http://127.0.0.1:9200
{
"name" : "Shard",
"cluster_name" : "elasticsearch",
"cluster_uuid" : "Pq6BQQhTQN6q6ML6ThPlbw",
"version" : {
"number" : "2.4.6",
"build_hash" : "5376dca9f70f3abef96a77f4bb22720ace8240fd",
"build_timestamp" : "2017-07-18T12:17:44Z",
"build_snapshot" : false,
"lucene_version" : "5.5.4"
},
"tagline" : "You Know, for Search"
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
3>安裝djangohaystack
3.1>安裝
# 安裝djangohaystack
# 使用的是當期最新版本 2.8.1
pip install django-haystack
- 1
- 2
- 3
3.2>配置文件
# 將Haystack添加到`INSTALLED_APPS`中
# settings.py
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'haystack',
'user',
'news',
'doc',
'course',
'verification'
]
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
# 配置搜索引擎
# 在settings.py中添加如下設置
# 全文搜索引擎haystack 配置
# 不同的搜索引擎,配置不同,詳情見官方文檔
HAYSTACK_CONNECTIONS = {
'default': {
'ENGINE': 'haystack.backends.elasticsearch_backend.ElasticsearchSearchEngine',
'URL': 'http://127.0.0.1:9200/', # 此處爲elasticsearch運行的服務器ip地址和端口
'INDEX_NAME': 'tzpython', # 指定elasticserach建立的索引庫名稱
},
}
# 搜索結果每頁顯示數量
HAYSTACK_SEARCH_RESULTS_PER_PAGE = 5
# 實時更新index
HAYSTACK_SIGNAL_PROCESSOR = ‘haystack.signals.RealtimeSignalProcessor’
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
3.3>安裝elasticsearch-py
haystack操作es還需要python的es驅動。兼容性見官網
根據官網,選擇2.4.1版本
pip install elasticsearch==2.4.1
- 1
至此,環境搭建完成。相對應的es,es-ik,haystack,es-python的版本請保持一致。
V. 新聞搜索功能實現
1>業務流程分析
設查詢文章時輸入的參數爲q
- 判斷是否傳遞查詢參數
q
- 如果沒有傳遞
q
,則直接返回熱門新聞數據 - 如果有傳遞,則返回查詢結果
- 分頁
2>接口設計
- 接口說明:
類目 | 說明 |
---|---|
請求方法 | GET |
url定義 | /news/search/ |
參數格式 | 查詢參數 |
- 參數說明:
參數名 | 類型 | 是否必須 | 描述 |
---|---|---|---|
q | 字符串 | 否 | 查詢的關鍵字 |
page | 整數 | 否 | 頁碼 |
-
返回結果:
搜索頁面html
3>後端代碼
3.1>創建haystack數據模型
在apps/news/目錄下創建search_indexes.py
文件,注意文件名必須使用search_indexes.py,代碼如下:
# !/usr/bin/env python
# -*- coding:utf-8 -*-
# create_time: 2019/7/13
# Author = '心藍'
from haystack import indexes
from .models import News
class NewsIndex(indexes.SearchIndex, indexes.Indexable):
“”"
這個模型的作用類似於django的模型,它告訴haystack哪些數據會被
放進查詢返回的模型對象中,以及通過哪些字段進行索引和查詢
“”"
# 這字段必須這麼寫,用來告訴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’)
<span class="token keyword">def</span> <span class="token function">get_model</span><span class="token punctuation">(</span>self<span class="token punctuation">)</span><span class="token punctuation">:</span>
<span class="token triple-quoted-string string">"""
返回建立索引的模型
:return:
"""</span>
<span class="token keyword">return</span> News
<span class="token keyword">def</span> <span class="token function">index_queryset</span><span class="token punctuation">(</span>self<span class="token punctuation">,</span> using<span class="token operator">=</span><span class="token boolean">None</span><span class="token punctuation">)</span><span class="token punctuation">:</span>
<span class="token triple-quoted-string string">"""
返回要建立索引的數據查詢集
:param using:
:return:
"""</span>
<span class="token comment"># 這種寫法遵從官方文檔的指引</span>
<span class="token keyword">return</span> self<span class="token punctuation">.</span>get_model<span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span>objects<span class="token punctuation">.</span><span class="token builtin">filter</span><span class="token punctuation">(</span>is_delete<span class="token operator">=</span><span class="token boolean">False</span><span class="token punctuation">)</span>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
3.2>創建索引數據模板
根據上面創建的模型中的第一個text
字段中的use_template=True
參數,還需要創建一個索引數據模板,用來告訴搜索引擎需要索引哪些字段。
在templates中創建文件search/indexes/<your app name>/<model name>_text.txt
,
所以本項目需要創建search/indexes/news/news_text.txt
,文件內容如下:
{{ object.title }}
{{ object.digest }}
{{ object.content }}
{{ object.author.username }}
- 1
- 2
- 3
- 4
3.3>創建索引
按上面的步驟配置好後,就可以運行haystack的命令創建索引了
~$ python manage.py rebuild_index # 看到如下信息,說明運行成功
WARNING: This will irreparably remove EVERYTHING from your search index in connection 'default'.
Your choices after this are to restore from backups or rebuild via the `rebuild_index` command.
Are you sure you wish to continue? [y/N] y
Removing all documents from your index because you said so.
All documents removed.
Indexing 889 新聞文章
GET /tzpython/_mapping [status:404 request:0.005s]
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
如果出現了get 404錯誤, 沒關係不用管它
3.4>視圖代碼
在news/views.py中添加如下視圖
from haystack.generic_views import SearchView
class NewsSearchView(SearchView):
“”"
新聞搜索視圖
“”"
# 設置搜索模板文件
template_name = ‘news/search.html’
<span class="token comment"># 重寫get請求,如果請求參數q爲空,返回模型News的熱門新聞數據</span>
<span class="token comment"># 否則根據參數q搜索相關數據</span>
<span class="token keyword">def</span> <span class="token function">get</span><span class="token punctuation">(</span>self<span class="token punctuation">,</span> request<span class="token punctuation">,</span> <span class="token operator">*</span>args<span class="token punctuation">,</span> <span class="token operator">**</span>kwargs<span class="token punctuation">)</span><span class="token punctuation">:</span>
<span class="token comment"># 1. 獲取查詢參數</span>
query <span class="token operator">=</span> request<span class="token punctuation">.</span>GET<span class="token punctuation">.</span>get<span class="token punctuation">(</span><span class="token string">'q'</span><span class="token punctuation">)</span>
<span class="token comment"># 2. 如果沒有查詢參數</span>
<span class="token keyword">if</span> <span class="token operator">not</span> query<span class="token punctuation">:</span>
<span class="token comment"># 則返回熱門新聞</span>
<span class="token comment"># 獲取熱門新聞對象, 包含外鍵標籤, 查詢數據並做篩選和排序</span>
hot_news <span class="token operator">=</span> HotNews<span class="token punctuation">.</span>objects<span class="token punctuation">.</span>select_related<span class="token punctuation">(</span><span class="token string">'news__tag'</span><span class="token punctuation">)</span><span class="token punctuation">.</span>only<span class="token punctuation">(</span><span class="token string">'news__title'</span><span class="token punctuation">,</span> <span class="token string">'news__image_url'</span><span class="token punctuation">,</span> <span class="token string">'news_id'</span><span class="token punctuation">,</span> <span class="token string">'news__tag__name'</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token builtin">filter</span><span class="token punctuation">(</span>is_delete<span class="token operator">=</span><span class="token boolean">False</span><span class="token punctuation">)</span><span class="token punctuation">.</span>order_by<span class="token punctuation">(</span><span class="token string">'priority'</span><span class="token punctuation">,</span> <span class="token string">'-news__clicks'</span><span class="token punctuation">)</span>
<span class="token comment"># 分頁, 從配置文件中拿到haystack參數</span>
paginator <span class="token operator">=</span> Paginator<span class="token punctuation">(</span>hot_news<span class="token punctuation">,</span> settings<span class="token punctuation">.</span>HAYSTACK_SEARCH_RESULTS_PER_PAGE<span class="token punctuation">)</span>
<span class="token keyword">try</span><span class="token punctuation">:</span>
<span class="token comment"># 拿到前端傳遞的page,</span>
page <span class="token operator">=</span> paginator<span class="token punctuation">.</span>get_page<span class="token punctuation">(</span><span class="token builtin">int</span><span class="token punctuation">(</span>request<span class="token punctuation">.</span>GET<span class="token punctuation">.</span>get<span class="token punctuation">(</span><span class="token string">'page'</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">)</span>
<span class="token keyword">except</span> Exception <span class="token keyword">as</span> e<span class="token punctuation">:</span>
<span class="token comment"># 如果出錯則返回第一頁,保證容錯性</span>
page <span class="token operator">=</span> paginator<span class="token punctuation">.</span>get_page<span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">)</span>
<span class="token keyword">return</span> render<span class="token punctuation">(</span>request<span class="token punctuation">,</span> self<span class="token punctuation">.</span>template_name<span class="token punctuation">,</span> context<span class="token operator">=</span><span class="token punctuation">{</span>
<span class="token string">'page'</span><span class="token punctuation">:</span> page<span class="token punctuation">,</span>
<span class="token comment">#'paginator': paginator,</span>
<span class="token string">'query'</span><span class="token punctuation">:</span> query
<span class="token punctuation">}</span><span class="token punctuation">)</span>
<span class="token comment"># 3. 如果有查詢參數</span>
<span class="token keyword">else</span><span class="token punctuation">:</span>
<span class="token comment"># 則執行搜索</span>
<span class="token keyword">return</span> <span class="token builtin">super</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span>get<span class="token punctuation">(</span>request<span class="token punctuation">,</span> <span class="token operator">*</span>args<span class="token punctuation">,</span> <span class="token operator">**</span>kwargs<span class="token punctuation">)</span>
<span class="token keyword">def</span> <span class="token function">get_context_data</span><span class="token punctuation">(</span>self<span class="token punctuation">,</span> <span class="token operator">*</span>args<span class="token punctuation">,</span> <span class="token operator">**</span>kwargs<span class="token punctuation">)</span><span class="token punctuation">:</span>
<span class="token triple-quoted-string string">"""
在context中添加page變量
"""</span>
context <span class="token operator">=</span> <span class="token builtin">super</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span>get_context_data<span class="token punctuation">(</span><span class="token operator">*</span>args<span class="token punctuation">,</span> <span class="token operator">**</span>kwargs<span class="token punctuation">)</span>
<span class="token keyword">if</span> context<span class="token punctuation">[</span><span class="token string">'page_obj'</span><span class="token punctuation">]</span><span class="token punctuation">:</span>
<span class="token comment"># 捕獲page_obj,將其賦值到page</span>
context<span class="token punctuation">[</span><span class="token string">'page'</span><span class="token punctuation">]</span> <span class="token operator">=</span> context<span class="token punctuation">[</span><span class="token string">'page_obj'</span><span class="token punctuation">]</span>
<span class="token keyword">return</span> context
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
3.5>路由
在news/urls.py中添加如下路由
path('news/search/', views.NewsSearchView.as_view(), name='news_search')
- 1
4>前端代碼
4.1>自定義過濾器
在news/templatetags/news_template_filters.py中定義一個處理分頁的過濾器
# !/usr/bin/env python
# -*- coding:utf-8 -*-
# create_time: 2019/7/14
# Author = '心藍'
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
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
4.2>前端html代碼
{% extends 'base/base.html' %}
{% load static %}
{% load news_customer_filters %}
{% block title %}新聞搜索{% endblock %}
{% block link %}
<link rel="stylesheet" href="{% static 'css/news/search.css' %}">
{% endblock %}
{% block main_contain %}
<!-- main-contain start -->
<div class=“main-contain “>
<!-- search-box start -->
<div class=“search-box”>
<form action=”” style=“display: inline-flex;”>
<span class="token tag"><span class="token tag"><span class="token punctuation"><</span>input</span> <span class="token attr-name">type</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>search<span class="token punctuation">"</span></span> <span class="token attr-name">placeholder</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>請輸入要搜索的內容<span class="token punctuation">"</span></span> <span class="token attr-name">name</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>q<span class="token punctuation">"</span></span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>search-control<span class="token punctuation">"</span></span><span class="token punctuation">></span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation"><</span>input</span> <span class="token attr-name">type</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>submit<span class="token punctuation">"</span></span> <span class="token attr-name">value</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>搜索<span class="token punctuation">"</span></span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>search-btn<span class="token punctuation">"</span></span><span class="token punctuation">></span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>form</span><span class="token punctuation">></span></span>
<span class="token comment"><!-- 可以用浮動 垂直對齊 以及 flex --></span>
<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>div</span><span class="token punctuation">></span></span>
<span class="token comment"><!-- search-box end --></span>
<span class="token comment"><!-- content start --></span>
<span class="token tag"><span class="token tag"><span class="token punctuation"><</span>div</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>content<span class="token punctuation">"</span></span><span class="token punctuation">></span></span>
{% if query %}
<span class="token comment"><!-- search-list start --></span>
<span class="token tag"><span class="token tag"><span class="token punctuation"><</span>div</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>search-result-list<span class="token punctuation">"</span></span><span class="token punctuation">></span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation"><</span>h2</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>search-result-title<span class="token punctuation">"</span></span><span class="token punctuation">></span></span>搜索結果 <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>span</span><span class="token punctuation">></span></span>{{ page.paginator.num_pages|default:0 }}<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>span</span><span class="token punctuation">></span></span> 頁<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>h2</span><span class="token punctuation">></span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation"><</span>ul</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>news-list<span class="token punctuation">"</span></span><span class="token punctuation">></span></span>
{% load highlight %}
{% for news in page.object_list %}
<span class="token tag"><span class="token tag"><span class="token punctuation"><</span>li</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>news-item clearfix<span class="token punctuation">"</span></span><span class="token punctuation">></span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation"><</span>a</span> <span class="token attr-name">href</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>{% url <span class="token punctuation">'</span>news:news_detail<span class="token punctuation">'</span> news.id %}<span class="token punctuation">"</span></span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>news-thumbnail<span class="token punctuation">"</span></span> <span class="token attr-name">target</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>_blank<span class="token punctuation">"</span></span><span class="token punctuation">></span></span><span class="token tag"><span class="token tag"><span class="token punctuation"><</span>img</span> <span class="token attr-name">src</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>{{ news.image_url }}<span class="token punctuation">"</span></span> <span class="token attr-name">alt</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span><span class="token punctuation">"</span></span><span class="token punctuation">></span></span><span class="token tag"><span class="token tag"><span class="token punctuation"></</span>a</span><span class="token punctuation">></span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation"><</span>div</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>news-content<span class="token punctuation">"</span></span><span class="token punctuation">></span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation"><</span>h4</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>news-title<span class="token punctuation">"</span></span><span class="token punctuation">></span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation"><</span>a</span> <span class="token attr-name">href</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>{% url <span class="token punctuation">'</span>news:news_detail<span class="token punctuation">'</span> news.id %}<span class="token punctuation">"</span></span><span class="token punctuation">></span></span>{% highlight news.title with query %}<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>a</span><span class="token punctuation">></span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>h4</span><span class="token punctuation">></span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation"><</span>p</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>news-details<span class="token punctuation">"</span></span><span class="token punctuation">></span></span>{{ news.digest }}<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>p</span><span class="token punctuation">></span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation"><</span>div</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>news-other<span class="token punctuation">"</span></span><span class="token punctuation">></span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation"><</span>span</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>news-type<span class="token punctuation">"</span></span><span class="token punctuation">></span></span>{{ news.object.tag.name }}<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>span</span><span class="token punctuation">></span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation"><</span>span</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>news-time<span class="token punctuation">"</span></span><span class="token punctuation">></span></span>{{ news.object.update_time }}<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>span</span><span class="token punctuation">></span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation"><</span>span</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>news-author<span class="token punctuation">"</span></span><span class="token punctuation">></span></span>{% highlight news.object.author.username with query %}<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>span</span><span class="token punctuation">></span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>div</span><span class="token punctuation">></span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>div</span><span class="token punctuation">></span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>li</span><span class="token punctuation">></span></span>
{% empty %}
<span class="token tag"><span class="token tag"><span class="token punctuation"><</span>li</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>news-item clearfix<span class="token punctuation">"</span></span><span class="token punctuation">></span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation"><</span>p</span><span class="token punctuation">></span></span>沒有找到你想要的找的內容.<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>p</span><span class="token punctuation">></span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>li</span><span class="token punctuation">></span></span>
{% endfor %}
<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>ul</span><span class="token punctuation">></span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>div</span><span class="token punctuation">></span></span>
<span class="token comment"><!-- search-list end --></span>
{% else %}
<span class="token comment"><!-- news-contain start --></span>
<span class="token tag"><span class="token tag"><span class="token punctuation"><</span>div</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>news-contain<span class="token punctuation">"</span></span><span class="token punctuation">></span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation"><</span>div</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>hot-recommend-list<span class="token punctuation">"</span></span><span class="token punctuation">></span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation"><</span>h2</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>hot-recommend-title<span class="token punctuation">"</span></span><span class="token punctuation">></span></span>熱門推薦<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>h2</span><span class="token punctuation">></span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation"><</span>ul</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>news-list<span class="token punctuation">"</span></span><span class="token punctuation">></span></span>
{% for hotnews in page %}
<span class="token tag"><span class="token tag"><span class="token punctuation"><</span>li</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>news-item clearfix<span class="token punctuation">"</span></span><span class="token punctuation">></span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation"><</span>a</span> <span class="token attr-name">href</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>#<span class="token punctuation">"</span></span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>news-thumbnail<span class="token punctuation">"</span></span><span class="token punctuation">></span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation"><</span>img</span> <span class="token attr-name">src</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>{{ hotnews.news.image_url }}<span class="token punctuation">"</span></span><span class="token punctuation">></span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>a</span><span class="token punctuation">></span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation"><</span>div</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>news-content<span class="token punctuation">"</span></span><span class="token punctuation">></span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation"><</span>h4</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>news-title<span class="token punctuation">"</span></span><span class="token punctuation">></span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation"><</span>a</span> <span class="token attr-name">href</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>{% url <span class="token punctuation">'</span>news:news_detail<span class="token punctuation">'</span> hotnews.news_id %}<span class="token punctuation">"</span></span><span class="token punctuation">></span></span>{{ hotnews.news.title }}<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>a</span><span class="token punctuation">></span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>h4</span><span class="token punctuation">></span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation"><</span>p</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>news-details<span class="token punctuation">"</span></span><span class="token punctuation">></span></span>{{ hotnews.news.digest }}<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>p</span><span class="token punctuation">></span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation"><</span>div</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>news-other<span class="token punctuation">"</span></span><span class="token punctuation">></span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation"><</span>span</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>news-type<span class="token punctuation">"</span></span><span class="token punctuation">></span></span>{{ hotnews.news.tag.name }}<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>span</span><span class="token punctuation">></span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation"><</span>span</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>news-time<span class="token punctuation">"</span></span><span class="token punctuation">></span></span>{{ hotnews.update_time }}<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>span</span><span class="token punctuation">></span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation"><</span>span</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>news-author<span class="token punctuation">"</span></span><span class="token punctuation">></span></span>{{ hotnews.news.author.username }}<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>span</span><span class="token punctuation">></span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>div</span><span class="token punctuation">></span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>div</span><span class="token punctuation">></span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>li</span><span class="token punctuation">></span></span>
{% endfor %}
<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>ul</span><span class="token punctuation">></span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>div</span><span class="token punctuation">></span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>div</span><span class="token punctuation">></span></span>
<span class="token comment"><!-- news-contain end --></span>
{% endif %}
<span class="token comment"><!-- Pagination start--></span>
<span class="token tag"><span class="token tag"><span class="token punctuation"><</span>div</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>page-box<span class="token punctuation">"</span></span> <span class="token attr-name">id</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>pages<span class="token punctuation">"</span></span><span class="token punctuation">></span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation"><</span>div</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>pagebar<span class="token punctuation">"</span></span> <span class="token attr-name">id</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>pageBar<span class="token punctuation">"</span></span><span class="token punctuation">></span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation"><</span>a</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>al<span class="token punctuation">"</span></span><span class="token punctuation">></span></span>{{ page.paginator.count|default:0 }}條<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>a</span><span class="token punctuation">></span></span>
<span class="token comment"><!-- prev page start--></span>
{% if page.has_previous %}
<span class="token comment"><!-- has_previous判斷是否有上一頁--></span>
{% if query %}
<span class="token comment"><!-- previous_page_number上一頁的頁碼--></span>
<span class="token tag"><span class="token tag"><span class="token punctuation"><</span>a</span> <span class="token attr-name">href</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>{% url <span class="token punctuation">'</span>news:news_search<span class="token punctuation">'</span> %}?q={{ query }}&page={{ page.previous_page_number }}<span class="token punctuation">"</span></span>
<span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>prev<span class="token punctuation">"</span></span><span class="token punctuation">></span></span>上一頁<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>a</span><span class="token punctuation">></span></span>
{% else %}
<span class="token tag"><span class="token tag"><span class="token punctuation"><</span>a</span> <span class="token attr-name">href</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>{% url <span class="token punctuation">'</span>news:news_search<span class="token punctuation">'</span> %}?page={{ page.previous_page_number }}<span class="token punctuation">"</span></span>
<span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>prev<span class="token punctuation">"</span></span><span class="token punctuation">></span></span>上一頁<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>a</span><span class="token punctuation">></span></span>
{% endif %}
{% endif %}
<span class="token comment"><!-- prev page end--></span>
<span class="token comment"><!-- page bar start--></span>
<span class="token comment"><!-- 有上一頁或是有下一頁時執行,若都沒有說明不需要分頁 --></span>
{% if page.has_previous or page.has_next %}
<span class="token comment"><!-- 使用自定義的過濾器來處理分頁 --></span>
{% for n in page|page_bar %}
{% if query %}
{% if n == '...' %}
<span class="token tag"><span class="token tag"><span class="token punctuation"><</span>span</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>point<span class="token punctuation">"</span></span><span class="token punctuation">></span></span>{{ n }}<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>span</span><span class="token punctuation">></span></span>
{% else %}
{% if n == page.number %}
<span class="token tag"><span class="token tag"><span class="token punctuation"><</span>span</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>sel<span class="token punctuation">"</span></span><span class="token punctuation">></span></span>{{ n }}<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>span</span><span class="token punctuation">></span></span>
{% else %}
<span class="token tag"><span class="token tag"><span class="token punctuation"><</span>a</span> <span class="token attr-name">href</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>{% url <span class="token punctuation">'</span>news:news_search<span class="token punctuation">'</span> %}?page={{ n }}&q={{ query }}<span class="token punctuation">"</span></span><span class="token punctuation">></span></span>{{ n }}<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>a</span><span class="token punctuation">></span></span>
{% endif %}
{% endif %}
{% else %}
{% if n == '...' %}
<span class="token tag"><span class="token tag"><span class="token punctuation"><</span>span</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>point<span class="token punctuation">"</span></span><span class="token punctuation">></span></span>{{ n }}<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>span</span><span class="token punctuation">></span></span>
{% else %}
{% if n == page.number %}
<span class="token tag"><span class="token tag"><span class="token punctuation"><</span>span</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>sel<span class="token punctuation">"</span></span><span class="token punctuation">></span></span>{{ n }}<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>span</span><span class="token punctuation">></span></span>
{% else %}
<span class="token tag"><span class="token tag"><span class="token punctuation"><</span>a</span> <span class="token attr-name">href</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>{% url <span class="token punctuation">'</span>news:news_search<span class="token punctuation">'</span> %}?page={{ n }}<span class="token punctuation">"</span></span><span class="token punctuation">></span></span>{{ n }}<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>a</span><span class="token punctuation">></span></span>
{% endif %}
{% endif %}
{% endif %}
{% endfor %}
{% endif %}
<span class="token comment"><!-- page bar end--></span>
<span class="token comment"><!-- next page start--></span>
{% if page.has_next %}
{% if query %}
<span class="token tag"><span class="token tag"><span class="token punctuation"><</span>a</span> <span class="token attr-name">href</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>{% url <span class="token punctuation">'</span>news:news_search<span class="token punctuation">'</span> %}?q={{ query }}&page={{ page.next_page_number }}<span class="token punctuation">"</span></span>
<span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>prev<span class="token punctuation">"</span></span><span class="token punctuation">></span></span>下一頁<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>a</span><span class="token punctuation">></span></span>
{% else %}
<span class="token tag"><span class="token tag"><span class="token punctuation"><</span>a</span> <span class="token attr-name">href</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>{% url <span class="token punctuation">'</span>news:news_search<span class="token punctuation">'</span> %}?page={{ page.next_page_number }}<span class="token punctuation">"</span></span>
<span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>prev<span class="token punctuation">"</span></span><span class="token punctuation">></span></span>下一頁<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>a</span><span class="token punctuation">></span></span>
{% endif %}
{% endif %}
<span class="token comment"><!-- next page end--></span>
<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>div</span><span class="token punctuation">></span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>div</span><span class="token punctuation">></span></span>
<span class="token comment"><!-- Pagination end--></span>
<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>div</span><span class="token punctuation">></span></span>
<span class="token comment"><!-- content end --></span>
<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>div</span><span class="token punctuation">></span></span>
<span class="token comment"><!-- main-contain end --></span>
{% endblock %}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
- 85
- 86
- 87
- 88
- 89
- 90
- 91
- 92
- 93
- 94
- 95
- 96
- 97
- 98
- 99
- 100
- 101
- 102
- 103
- 104
- 105
- 106
- 107
- 108
- 109
- 110
- 111
- 112
- 113
- 114
- 115
- 116
- 117
- 118
- 119
- 120
- 121
- 122
- 123
- 124
- 125
- 126
- 127
- 128
- 129
- 130
- 131
- 132
- 133
- 134
- 135
- 136
- 137
- 138
- 139
- 140
- 141
- 142
- 143
- 144
- 145
- 146
- 147
- 148
- 149
- 150
- 151
- 152
- 153
- 154
- 155
- 156
- 157
- 158
- 159
4.3>css代碼
修改static/css/news/search.css如下:
/* ================= main start ================= */
#main {
margin-top: 25px;
min-height: 700px;
}
/* ========= main-contain start ============ */
#main .main-contain {
width: 800px;
float: left;
background: #fff;
}
/* === search-box start === /
.main-contain .search-box {
padding: 40px 50px;
width: 700px;
box-shadow: 1px 2px rgba(0,0,0,.1);
display: inline-flex;
}
.main-contain .search-box .search-control {
width: 600px;
height: 40px;
border-radius: 20px 0 0 20px;
border: 1px solid #ddd;
border-right: none;
padding-left: 0.88em;
font-size: 20px;
}
.main-contain .search-box .search-btn {
width: 100px;
height: 40px;
border: 1px solid red;
background: red;
color: #fff;
font-size: 20px;
border-radius: 0 20px 20px 0;
cursor: pointer;
}
/ === search-box end === */
/* === content start === /
/ == search-list start == /
.content .search-result-list {
padding-top: 20px;
}
.content .search-result-list .search-result-title {
padding-left: 20px;
font-size: 20px;
line-height: 26px;
}
.content .search-result-list .search-result-title span {
font-weight: 700;
color: #ff6620;
}
/ == search-list end == /
/ == news-contain start == /
.content .news-contain .hot-recommend-list {
padding-top: 20px;
}
.hot-recommend-list .hot-recommend-title {
padding-left: 20px;
font-size: 20px;
line-height: 26px;
}
.content .news-contain li {
border-bottom: 1px solid #ededed;
}
.news-list .news-item {
padding: 20px;
}
.news-list .news-item .news-thumbnail {
float: left;
width: 224px;
height: 160px;
margin-right: 30px;
overflow: hidden;
}
.news-item .news-thumbnail img {
width: 100%;
height: 100%;
transition: all 0.3s ease-out;
}
.news-item .news-thumbnail:hover img {
transform: scale(1.1);
transition: all 0.3s ease-in;
}
.news-list .news-item .news-content {
width: 500px;
height: 170px;
float: right;
color: #878787;
font-size: 14px;
}
.news-item .news-content .news-title{
color: #212121;
font-size: 22px;
height: 52px;
line-height: 26px;
transition:all 0.3s ease-out;
}
.news-item .news-content .news-title:hover {
color: #5b86db;
transition:all 0.3s ease-in;
}
.news-item .news-content .news-details {
height: 44px;
line-height: 22px;
margin-top: 19px;
text-align: justify;
}
.news-item .news-content .news-other {
margin-top: 30px;
}
.news-content .news-other .news-type {
color: #5b86db;
}
.news-content .news-other .news-author {
float: right;
margin-right: 15px;
}
.news-content .news-other .news-time {
float: right;
}
/ === 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
}
#pages .point {
display: inline-block;
height: 26px;
line-height: 26px;
background: #fff;
border: 1px solid #e3e3e3;
text-align: center;
color: #333;
padding: 0 10px
}
.highlighted {
font-weight: 700;
color: #ff6620;
}
/* === current index end === /
/ === content end === /
/ ================= main end ================= */
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
- 85
- 86
- 87
- 88
- 89
- 90
- 91
- 92
- 93
- 94
- 95
- 96
- 97
- 98
- 99
- 100
- 101
- 102
- 103
- 104
- 105
- 106
- 107
- 108
- 109
- 110
- 111
- 112
- 113
- 114
- 115
- 116
- 117
- 118
- 119
- 120
- 121
- 122
- 123
- 124
- 125
- 126
- 127
- 128
- 129
- 130
- 131
- 132
- 133
- 134
- 135
- 136
- 137
- 138
- 139
- 140
- 141
- 142
- 143
- 144
- 145
- 146
- 147
- 148
- 149
- 150
- 151
- 152
- 153
- 154
- 155
- 156
- 157
- 158
- 159
- 160
- 161
- 162
- 163
- 164
- 165
- 166
- 167
- 168
- 169
- 170
- 171
- 172
- 173
- 174
- 175
- 176
4.4>js代碼
搜索頁面的js代碼於新聞頁面的雷同, 僅僅只需要改一些參數即可
$(() => { let iPage = 1; // 當前頁面頁數 let iTotalPage = 1; // 總頁數 let bIsLoadData =false; // 是否正在加載 fn_load_docs(); // 加載文件列表 // 頁面滾動加載 $(window).scroll(function () { // 瀏覽器窗口高度 let showHeight = $(window).height(); // 整個網頁高度 let pageHeight = $(document).height(); //頁面可以滾動的距離 let canScrollHeight = pageHeight - showHeight; // 頁面滾動了多少, 整個是隨着頁面滾動實時變化的 let nowScroll = $(document).scrollTop(); if ((canScrollHeight - nowScroll) < 100){ if(!bIsLoadData){ bIsLoadData = true; //判斷頁數,去更新新聞,小於總數才加載 if(iPage < iTotalPage){ iPage += 1; fn_load_docs();
<span class="token punctuation">}</span><span class="token keyword">else</span> <span class="token punctuation">{</span> message<span class="token punctuation">.</span><span class="token function">showInfo</span><span class="token punctuation">(</span><span class="token string">'已全部加載,沒有更多內容!'</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token function">$</span><span class="token punctuation">(</span><span class="token string">'a.btn-more'</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">html</span><span class="token punctuation">(</span><span class="token string">'已全部加載,沒有更多內容!'</span><span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 獲取docs信息</span> <span class="token keyword">function</span> <span class="token function">fn_load_docs</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> $ <span class="token punctuation">.</span><span class="token function">ajax</span><span class="token punctuation">(</span><span class="token punctuation">{</span> url<span class="token punctuation">:</span> <span class="token string">'/doc/docs'</span><span class="token punctuation">,</span> type<span class="token punctuation">:</span> <span class="token string">'GET'</span><span class="token punctuation">,</span> data<span class="token punctuation">:</span> <span class="token punctuation">{</span>page<span class="token punctuation">:</span> iPage<span class="token punctuation">}</span><span class="token punctuation">,</span> dataType<span class="token punctuation">:</span> <span class="token string">'json'</span> <span class="token punctuation">}</span><span class="token punctuation">)</span> <span class="token punctuation">.</span><span class="token function">done</span><span class="token punctuation">(</span><span class="token punctuation">(</span>res<span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>res<span class="token punctuation">.</span>errno <span class="token operator">===</span> <span class="token string">'0'</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> iTotalPage <span class="token operator">=</span> res<span class="token punctuation">.</span>data<span class="token punctuation">.</span>total_page<span class="token punctuation">;</span> res<span class="token punctuation">.</span>data<span class="token punctuation">.</span>docs<span class="token punctuation">.</span><span class="token function">forEach</span><span class="token punctuation">(</span><span class="token punctuation">(</span>doc<span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token keyword">let</span> content <span class="token operator">=</span> <span class="token template-string"><span class="token string">`<li class="pay-item"> <div class="pay-img doc"></div> <img src="</span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span> doc<span class="token punctuation">.</span>image_url <span class="token interpolation-punctuation punctuation">}</span></span><span class="token string">" alt="" class="pay-img doc"> <div class="d-contain"> <p class="doc-title"></span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span> doc<span class="token punctuation">.</span>title <span class="token interpolation-punctuation punctuation">}</span></span><span class="token string"></p> <p class="doc-desc"></span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span> doc<span class="token punctuation">.</span>desc <span class="token interpolation-punctuation punctuation">}</span></span><span class="token string"></p> <!-- /www/?xxx --> <a href="</span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span> doc<span class="token punctuation">.</span>file_url <span class="token interpolation-punctuation punctuation">}</span></span><span class="token string">" class="pay-price" download="</span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span> doc<span class="token punctuation">.</span>file_name <span class="token interpolation-punctuation punctuation">}</span></span><span class="token string">">下載</a> </div> </li>`</span></span><span class="token punctuation">;</span> <span class="token function">$</span><span class="token punctuation">(</span><span class="token string">'.pay-list'</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">append</span><span class="token punctuation">(</span>content<span class="token punctuation">)</span><span class="token punctuation">;</span> bIsLoadData <span class="token operator">=</span> <span class="token boolean">false</span><span class="token punctuation">;</span> <span class="token function">$</span><span class="token punctuation">(</span><span class="token string">'a.btn-more'</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">html</span><span class="token punctuation">(</span><span class="token string">'滾動加載更多'</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token punctuation">{</span> message<span class="token punctuation">.</span><span class="token function">showError</span><span class="token punctuation">(</span>res<span class="token punctuation">.</span>errmsg<span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span><span class="token punctuation">)</span> <span class="token punctuation">.</span><span class="token function">fail</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> message<span class="token punctuation">.</span><span class="token function">showError</span><span class="token punctuation">(</span><span class="token string">'服務器超時,請重試!'</span><span class="token punctuation">)</span> <span class="token punctuation">}</span><span class="token punctuation">)</span> <span class="token punctuation">}</span>
});
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
編寫完上述代碼後就可以運行搜索了,如果運行過程中出現搜索不到結果的問題,請先去檢查docker容器的運行狀態,到控制檯中輸入:curl http://127.0.0.1:9200
查看狀態,若連接失敗並且輸入docker ps
時沒有內容,那麼說明docker沒有運行,使用以下方法可以設置docker容器的啓動
VI. docker 容器相關啓動
docker 是安裝在ubuntu中的,所以如果你重啓了ubuntu,創建好的elasticsearch容器當然也會關閉。那怎麼打開關閉的容器呢?
-
先查詢容器名, 運行命令:
docker ps -a
- 1
-
找到你要啓動的容器名,然後運行命令
docker start 容器名
- 1
即可啓動容器
如果希望docker容器能夠遇到錯誤自動重啓, 則可以在創建容器時攜帶參數:
docker run --restart=on-failure
- 1
如果已經創建了docker容器, 則可以通過update來更新設置:
docker update --restart=on-failure <CONTAINER ID>
- 1
其他參數的參考如下:
Flag | Description |
---|---|
no | 不自動重啓容器. (默認value) |
on-failure | 容器發生error而退出(容器退出狀態不爲0)重啓容器 |
unless-stopped | 在容器已經stop掉或Docker stoped/restarted的時候才重啓容器 |
always | 在容器已經stop掉或Docker stoped/restarted的時候才重啓容器 |
如果想要docker容器開機自啓, 可以參考如下設置方法:[reboot 後 Docker服務及容器自動啓動設置](https://blog.csdn.net/wxb880114/article/details/82904765
</div>
<link href="https://csdnimg.cn/release/phoenix/mdeditor/markdown_views-095d4a0b23.css" rel="stylesheet">
</div>
</article>
<div class="postTime">
<p class="article-bar-bottom"></p>
<span>
文章最後發佈於: 2019年08月25日 11:45:54 </span>
</div>