[django項目] 利用elasticsearch實現搜索功能 [django項目] 利用elasticsearch實現搜索功能

原創

[django項目] 利用elasticsearch實現搜索功能

新聞搜索

I. 搜索功能分析

本節我們來完成新聞搜索功能, 首先讓我們來思考一下,要做一個通過關鍵詞搜索文章的功能,需要搜索哪些字段,以及使用什麼技術方案呢?

既然我們是準備做新聞博客網站, 那我們就可以拿同類型網站的做一下對比, 例如CSDN, 簡書, 博客園等, 這些常見的博客網站其主要覆蓋的搜索字段有:

  1. 標題
  2. 內容
  3. 作者

實現這些字段檢索的技術方案有以下兩種:

  1. mysql的模糊查詢 %like%
    1. 優點:實現起來簡單
    2. 缺點:數據量比較大的情況下,查詢效率極低
  2. 全文檢索引擎
    1. 優點:專業的全文檢索引擎,效率高
    2. 缺點:實現起來比較複雜

本項目選擇使用過全文檢索引擎。自行實現django框架和全文檢索引擎的代碼比較麻煩,抱着不重複造輪子的原則,這裏我們選用django的第三方包djangohaystack。它支持多種全文檢索引擎,本項目選擇最流行的全文檢索引擎之一elasticsearch

II. elasticsearch介紹

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

工作原理示意圖

[外鏈圖片轉存失敗(img-HvAY3Wat-1566702560769)(E:\Fire\QQfire\992994875\FileRecv\Django項目_心藍班\7.新聞搜索\assets\1566393245580.png)]

  1. 首先來看圖中, 用戶將全文搜索的請求發送至django, 即輸入搜索內容
  2. 全文搜索需要分詞模糊查詢, 這些操作在mysql中也可以使用, 但如果遇到數據量大的項目, 效率會很低, 因此, 就需要藉助搜索引擎elasticsearch
  3. 要實現查詢, 那麼我們的django需要連接mysqlelasticsearch:
    1. 連接mysql使用的是mysqlclient
    2. 連接elasticsearch使用的是django-haystack, 以及python的es驅動
  4. elasticsearch會去到mysql中獲取數據, 然後進行索引, 並儲存到它自己那裏
  5. 然後django就會利用haystack到elasticsearch中查詢想要的數據, 即執行搜索
  6. es查詢到後返回給haystack(haystack是屬於django項目中的一個從外部引入的app)
  7. haystack會返回給django框架, 然後django再展示給用戶看, 即展示搜索結果

III. docker介紹與安裝

1>docker介紹

1.1>什麼是docker?

  • 簡化創建,部署,運行應用程序的一個工具
  • 打包應用程序所需的庫和依賴環境
  • 精簡的虛擬機

[外鏈圖片轉存失敗(img-9KJ8jUaW-1566702560769)(新聞搜索.assets/what_is_docker.png)]

1.2>爲什麼使用docker?

why_to_use_docker_1.png

流行,方便,強大

1.3>docker vs 虛擬機

[外鏈圖片轉存失敗(img-Zu2k2B3U-1566702560770)(新聞搜索.assets/VM-vs-Docker-What-is-Docker-Container-Edureka-1.png)]

[外鏈圖片轉存失敗(img-bg6kbWn7-1566702560771)(新聞搜索.assets/docker-vm-container.png)]

1.4>docker架構

[外鏈圖片轉存失敗(img-OpVPQr6l-1566702560772)(新聞搜索.assets/1563198966139.png)]

  • 架構

    • 客戶端
    • 守護進程
    • 倉庫
  • docker 對象

    • 鏡像 精簡的linux
    • 容器
    • 服務
  • docker Hub

  • 安裝

    官方安裝文檔

    lsb_release -a   # 查看系統信息
    uname -a		# 查看位數
    
    • 1
    • 2

2>ubuntu下安裝

如果是第一次安裝,你需要先添加docker的源然後再安裝

2.1>添加阿里雲源

  1. 百度搜索"阿里雲源"
  2. 選擇Ubuntu然後複製源鏈接
  3. 桌面創建一個txt文件, 重命名爲sources.list
  4. 使用NotePad++或是pycharm打開, 粘貼源鏈接, 保存
  5. 粘貼文件到linux的家目錄
  6. cd /etc/apt/
  7. 備份原有的sources.list, 使用命令: sudo cp sources.list sources.dbk.list
  8. 然後sudo rm sources.list, 再將你剛纔創建的sources.list拷貝到/etc/apt/
  9. 運行命令: sudo apt-get update, 刷新源
  10. 如果有問題則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:

  1. The Docker client contacted the Docker daemon.
  2. The Docker daemon pulled the “hello-world” image from the Docker Hub.
    (amd64)
  3. The Docker daemon created a new container from that image which runs the
    executable that produces the output you are currently reading.
  4. 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

[外鏈圖片轉存失敗(img-0oOzRk0J-1566702560772)(新聞搜索.assets/)]

因爲直接使用elasticsearch的plugin命令安裝會報錯,所以通過下載後解壓到相應文件夾的方式安裝。

新聞搜索.assets/1563190261012.png)]

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驅動。兼容性見官網

[外鏈圖片轉存失敗(img-1BesZeeK-1566702560773)()]

根據官網,選擇2.4.1版本

pip install elasticsearch==2.4.1
  • 1

至此,環境搭建完成。相對應的es,es-ik,haystack,es-python的版本請保持一致。

V. 新聞搜索功能實現

1>業務流程分析

設查詢文章時輸入的參數爲q

  • 判斷是否傳遞查詢參數q
  • 如果沒有傳遞q,則直接返回熱門新聞數據
  • 如果有傳遞,則返回查詢結果
  • 分頁

2>接口設計

  1. 接口說明:
類目 說明
請求方法 GET
url定義 /news/search/
參數格式 查詢參數
  1. 參數說明:
參數名 類型 是否必須 描述
q 字符串 查詢的關鍵字
page 整數 頁碼
  1. 返回結果:

    搜索頁面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">&lt;</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">&gt;</span></span>


            <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</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">&gt;</span></span>
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>form</span><span class="token punctuation">&gt;</span></span>
        <span class="token comment">&lt;!-- 可以用浮動 垂直對齊 以及 flex  --&gt;</span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>
    <span class="token comment">&lt;!-- search-box end --&gt;</span>
    <span class="token comment">&lt;!-- content start --&gt;</span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</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">&gt;</span></span>
        {% if query %}
            <span class="token comment">&lt;!-- search-list start --&gt;</span>
            <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</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">&gt;</span></span>
                <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</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">&gt;</span></span>搜索結果 <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>span</span><span class="token punctuation">&gt;</span></span>{{ page.paginator.num_pages|default:0 }}<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>span</span><span class="token punctuation">&gt;</span></span> 頁<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>h2</span><span class="token punctuation">&gt;</span></span>
                <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</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">&gt;</span></span>
                    {% load highlight %}
                    {% for news in page.object_list %}
                        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</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">&gt;</span></span>
                            <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</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">&gt;</span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</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">&gt;</span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>a</span><span class="token punctuation">&gt;</span></span>
                            <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</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">&gt;</span></span>
                                <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</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">&gt;</span></span>
                                    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</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">&gt;</span></span>{% highlight news.title with query %}<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>a</span><span class="token punctuation">&gt;</span></span>
                                <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>h4</span><span class="token punctuation">&gt;</span></span>
                                <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</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">&gt;</span></span>{{ news.digest }}<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>p</span><span class="token punctuation">&gt;</span></span>
                                <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</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">&gt;</span></span>
                                    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</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">&gt;</span></span>{{ news.object.tag.name }}<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>span</span><span class="token punctuation">&gt;</span></span>
                                    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</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">&gt;</span></span>{{ news.object.update_time }}<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>span</span><span class="token punctuation">&gt;</span></span>
                                    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</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">&gt;</span></span>{% highlight news.object.author.username with query %}<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>span</span><span class="token punctuation">&gt;</span></span>
                                <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>
                            <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>

                        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>li</span><span class="token punctuation">&gt;</span></span>
                    {% empty %}
                        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</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">&gt;</span></span>
                            <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>p</span><span class="token punctuation">&gt;</span></span>沒有找到你想要的找的內容.<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>p</span><span class="token punctuation">&gt;</span></span>
                        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>li</span><span class="token punctuation">&gt;</span></span>
                    {% endfor %}
                <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>ul</span><span class="token punctuation">&gt;</span></span>
            <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>

            <span class="token comment">&lt;!-- search-list end --&gt;</span>
        {% else %}
            <span class="token comment">&lt;!-- news-contain start --&gt;</span>

            <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</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">&gt;</span></span>
                <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</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">&gt;</span></span>
                    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</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">&gt;</span></span>熱門推薦<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>h2</span><span class="token punctuation">&gt;</span></span>
                    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</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">&gt;</span></span>
                        {% for hotnews in page %}
                            <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</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">&gt;</span></span>
                                <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</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">&gt;</span></span>
                                    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</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">&gt;</span></span>
                                <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>a</span><span class="token punctuation">&gt;</span></span>
                                <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</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">&gt;</span></span>
                                    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</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">&gt;</span></span>
                                        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</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">&gt;</span></span>{{ hotnews.news.title }}<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>a</span><span class="token punctuation">&gt;</span></span>
                                    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>h4</span><span class="token punctuation">&gt;</span></span>
                                    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</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">&gt;</span></span>{{ hotnews.news.digest }}<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>p</span><span class="token punctuation">&gt;</span></span>
                                    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</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">&gt;</span></span>
                                        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</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">&gt;</span></span>{{ hotnews.news.tag.name }}<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>span</span><span class="token punctuation">&gt;</span></span>
                                        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</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">&gt;</span></span>{{ hotnews.update_time }}<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>span</span><span class="token punctuation">&gt;</span></span>
                                        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</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">&gt;</span></span>{{ hotnews.news.author.username }}<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>span</span><span class="token punctuation">&gt;</span></span>
                                    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>
                                <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>
                            <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>li</span><span class="token punctuation">&gt;</span></span>
                        {% endfor %}


                    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>ul</span><span class="token punctuation">&gt;</span></span>
                <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>
            <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>


            <span class="token comment">&lt;!-- news-contain end --&gt;</span>
        {% endif %}
        <span class="token comment">&lt;!-- Pagination start--&gt;</span>
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</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">&gt;</span></span>
            <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</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">&gt;</span></span>
                <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</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">&gt;</span></span>{{ page.paginator.count|default:0 }}條<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>a</span><span class="token punctuation">&gt;</span></span>
                <span class="token comment">&lt;!-- prev page start--&gt;</span>
                {% if page.has_previous %}
                <span class="token comment">&lt;!-- has_previous判斷是否有上一頁--&gt;</span>
                    {% if query %}
                	<span class="token comment">&lt;!-- previous_page_number上一頁的頁碼--&gt;</span>
                        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</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 }}&amp;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">&gt;</span></span>上一頁<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>a</span><span class="token punctuation">&gt;</span></span>
                    {% else %}
                        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</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">&gt;</span></span>上一頁<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>a</span><span class="token punctuation">&gt;</span></span>
                    {% endif %}
                {% endif %}
                <span class="token comment">&lt;!-- prev page end--&gt;</span>

             <span class="token comment">&lt;!-- page bar start--&gt;</span>
             <span class="token comment">&lt;!-- 有上一頁或是有下一頁時執行,若都沒有說明不需要分頁 --&gt;</span>
            {% if page.has_previous or page.has_next %}
            <span class="token comment">&lt;!-- 使用自定義的過濾器來處理分頁 --&gt;</span>
                {% for n in page|page_bar %}
                    {% if query %}
                        {% if n == '...' %}
                        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</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">&gt;</span></span>{{ n }}<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>span</span><span class="token punctuation">&gt;</span></span>
                        {% else %}
                            {% if n == page.number %}
                                <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</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">&gt;</span></span>{{ n }}<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>span</span><span class="token punctuation">&gt;</span></span>
                            {% else %}
                                <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</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 }}&amp;q={{ query }}<span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span>{{ n }}<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>a</span><span class="token punctuation">&gt;</span></span>
                            {% endif %}
                        {% endif %}
                    {% else %}
                        {% if n == '...' %}
                            <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</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">&gt;</span></span>{{ n }}<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>span</span><span class="token punctuation">&gt;</span></span>
                        {% else %}
                            {% if n == page.number %}
                                <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</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">&gt;</span></span>{{ n }}<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>span</span><span class="token punctuation">&gt;</span></span>
                            {% else %}
                                <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</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">&gt;</span></span>{{ n }}<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>a</span><span class="token punctuation">&gt;</span></span>
                            {% endif %}
                        {% endif %}
                    {% endif %}
                {% endfor %}
            {% endif %}
                <span class="token comment">&lt;!-- page bar end--&gt;</span>

                <span class="token comment">&lt;!-- next page start--&gt;</span>
                {% if page.has_next %}
                    {% if query %}
                        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</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 }}&amp;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">&gt;</span></span>下一頁<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>a</span><span class="token punctuation">&gt;</span></span>
                    {% else %}
                        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</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">&gt;</span></span>下一頁<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>a</span><span class="token punctuation">&gt;</span></span>
                    {% endif %}
                {% endif %}
                <span class="token comment">&lt;!-- next page end--&gt;</span>


            <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>
        <span class="token comment">&lt;!-- Pagination end--&gt;</span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>
    <span class="token comment">&lt;!-- content end --&gt;</span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>
<span class="token comment">&lt;!-- main-contain  end --&gt;</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">=&gt;</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">=&gt;</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">`&lt;li class="pay-item"&gt;
                    &lt;div class="pay-img doc"&gt;&lt;/div&gt;
                       &lt;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"&gt;
                    &lt;div class="d-contain"&gt;
                        &lt;p class="doc-title"&gt;</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">&lt;/p&gt;
                        &lt;p class="doc-desc"&gt;</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">&lt;/p&gt;

                        &lt;!-- /www/?xxx --&gt;
                        &lt;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">"&gt;下載&lt;/a&gt;
                    &lt;/div&gt;
                &lt;/li&gt;`</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">=&gt;</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容器當然也會關閉。那怎麼打開關閉的容器呢?

  1. 先查詢容器名, 運行命令:

    docker ps -a
    
    • 1
  2. 找到你要啓動的容器名,然後運行命令

    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>
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章