Diango博客--22.Django Haystack 全文檢索與關鍵詞高亮

文章目錄

  • 1. Django Haystack 簡介
  • 2. 安裝 django-haystack和elasticsearch 2
  • 3. 構建容器來運行 elasticsearch 服務
  • 4. 配置 Haystack
  • 5. 處理數據
  • 6. 配置 URL
  • 7. 修改搜索表單
  • 8. 創建搜索結果頁面
  • 9. 高亮關鍵詞
  • 10. 建立索引文件
  • 11. 修改搜索引擎為中文分詞
  • 12. 防止標題被截斷
  • 13. 線上發布

1. Django Haystack 簡介

在此之前我們使用了 Django 內置的一些方法實現了一個簡單的搜索功能。但這個搜索功能實在過于簡單,沒有多大的實用性。對于一個搜索引擎來說,至少應該能夠根據用戶的搜索關鍵詞對搜索結果進行排序以及高亮關鍵字。現在我們就來使用 django-haystack 實現這些特性。

jango-haystack 是一個專門提供搜索功能的 django 第三方應用,它支持 Solr、Elasticsearch、Whoosh、Xapian 等多種搜索引擎,上一版本的教程中我們使用 Whoosh 加 jieba 中文分詞的方案,原因是為了簡單,無需安裝外部服務。但現在有了 docker,安裝一個外部服務就是輕而易舉的事情,所以這次我們采用更為強大的 elasticsearch 作為我們博客的搜索引擎,同時使用 elasticsearch 的中文分詞插件 ik,來提升中文搜索的效果。

2. 安裝 django-haystack和elasticsearch 2

django-haystack 安裝非常簡單,只需要執行 pipenv install django-haystack 即可。需要注意的是,目前 elasticsearch 有 2 系列和 5 系列兩大版本,本來新項目的原則是盡可能采用新版本,但目前 django-haystack 在 pypi 上發布的穩定版只支持 elasticsearch2,master 分支下支持 elasticsearch5,因此處于穩定性考慮,我們暫時使用 elasticsearch2,后續如果 django-haystack 發布了支持 elasticsearch5 的pypi版本,我們會升級到 elasticsearch5,有了 docker,升級就是輕而易舉的事情。

由于使用 elasticsearch 服務,這里我們不要直接使用 pipenv 安裝,而是手動編輯 Pipfile 文件,指定 SDK 的版本,否則 pipenv 默認會安裝最新版。打開 Pipfile 文件,將依賴手動添加到 packages 板塊下:

[packages]
django = "~=2.2"
django-haystack = "*"
elasticsearch = ">=2,<3"

3. 構建容器來運行 elasticsearch 服務

接下來就是構建一個新的容器來運行 elasticsearch 服務,因此首先需要來編排容器鏡像,回顧一下容器鏡像的目錄結構:
在這里插入圖片描述
由于 elasticsearch 在線上環境和本地測試都要使用,我們把鏡像編排在 production 目錄下,新建一個 elasticsearch 目錄,用來存放和 elasticsearch 相關的內容。Dockfile 內容如下:

FROM elasticsearch:2.4.6-alpineCOPY ./compose/production/elasticsearch/elasticsearch-analysis-ik-1.10.6.zip /usr/share/elasticsearch/plugins/
RUN cd /usr/share/elasticsearch/plugins/ && mkdir ik && unzip elasticsearch-analysis-ik-1.10.6.zip -d ik/
RUN rm /usr/share/elasticsearch/plugins/elasticsearch-analysis-ik-1.10.6.zipUSER root
COPY ./compose/production/elasticsearch/elasticsearch.yml /usr/share/elasticsearch/config/
RUN chown elasticsearch:elasticsearch /usr/share/elasticsearch/config/elasticsearch.ymlUSER elasticsearch

這個鏡像從 elasticsearch 的官方基礎鏡像 2.4.6 版本進行構建,接著我們把 ik 分詞插件復制到 elasticsearch 安裝插件的目錄下,然后解壓啟用。

接著我們又把 elasticsearch.yml 配置文件復制到容器內,然后切換用戶為 elasticsearch,因為我們將以 elasticsearch 用戶和組運行 elasticsearch 服務。

elasticsearch.yml 配置文件內容很簡單:

bootstrap.memory_lock: true
network.host: 0.0.0.0

其中 bootstrap.memory_lock 這個參數是為了提高 elasticsearch 的效率(涉及到 JVM 相關的優化,不做過多介紹)。network.host 指定服務啟動的地址。

接著修改 docker compose 文件,我們先在本地啟動,因此修改 local.yml 文件,加入 elasticsearch 服務:

version: '3'volumes:database_local:esdata_local:services:hellodjango_blog_tutorial_local:# 其它配置不變...depends_on:- elasticsearch_localelasticsearch_local:build:context: .dockerfile: ./compose/production/elasticsearch/Dockerfileimage: elasticsearch_localcontainer_name: elasticsearch_localvolumes:- esdata_local:/usr/share/elasticsearch/dataports:- "9200:9200"environment:- "ES_JAVA_OPTS=-Xms512m -Xmx512m"ulimits:memlock:soft: -1hard: -1nproc: 65536nofile:soft: 65536hard: 65536

主要是加入了 elasticsearch 服務,其中 environment 和 ulimits 的參數與 elasticksearch 服務調優有關,對于簡單的博客搜索來說,調優的意義不是很大,因此這里不做過多介紹,感興趣的可以參考 elasticksearch 的官方文檔。

4. 配置 Haystack

安裝好 django haystack 后需要在項目的 settings.py 做一些簡單的配置。

首先是把 django haystack 加入到 INSTALLED_APPS 設置里:

文件位置:blogproject\settings\common.py

INSTALLED_APPS = ['django.contrib.admin',# 其它 app...'haystack','blog','comments',
]

然后加入如下配置項

# 搜索設置
HAYSTACK_CONNECTIONS = {'default': {'ENGINE': 'haystack.elasticsearch2_backend.Elasticsearch2SearchEngine','URL': '','INDEX_NAME': 'hellodjango_blog_tutorial',},
}
HAYSTACK_SEARCH_RESULTS_PER_PAGE = 10
HAYSTACK_SIGNAL_PROCESSOR = 'haystack.signals.RealtimeSignalProcessor'

HAYSTACK_CONNECTIONS 的 ENGINE 指定了 django haystack 使用的搜索引擎,這里我們使用了 haystack 默認的 Elasticsearch2 搜索引擎。PATH 指定了索引文件需要存放的位置,我們設置為項目根目錄 BASE_DIR 下的 whoosh_index 文件夾(在建立索引是會自動創建)。

HAYSTACK_SEARCH_RESULTS_PER_PAGE 指定如何對搜索結果分頁,這里設置為每 10 項結果為一頁。

HAYSTACK_SIGNAL_PROCESSOR 指定什么時候更新索引,這里我們使用 haystack.signals.RealtimeSignalProcessor,作用是每當有文章更新時就更新索引。由于博客文章更新不會太頻繁,因此實時更新沒有問題。

由于開發環境和線上環境,elasticsearch 服務的 url 地址是不同的,所以我們在 common 的配置中沒有指定 url,在 local.py 設置文件指定之:

文件位置:blogproject/settings/local.py

HAYSTACK_CONNECTIONS['default']['URL'] = 'http://elasticsearch_local:9200/'

5. 處理數據

接下來就要告訴 django haystack 使用哪些數據建立索引以及如何存放索引。如果要對 blog 應用下的數據進行全文檢索,做法是在 blog 應用下建立一個 search_indexes.py 文件,寫上如下代碼:

文件位置:blog/search_indexes.py

from haystack import indexes
from .models import Postclass PostIndex(indexes.SearchIndex, indexes.Indexable):text = indexes.CharField(document=True, use_template=True)def get_model(self):return Postdef index_queryset(self, using=None):return self.get_model().objects.all()

這是 django haystack 的規定。要相對某個 app 下的數據進行全文檢索,就要在該 app 下創建一個 search_indexes.py 文件,然后創建一個 XXIndex 類(XX 為含有被檢索數據的模型,如這里的 Post),并且繼承 SearchIndex 和 Indexable。

為什么要創建索引?索引就像是一本書的目錄,可以為讀者提供更快速的導航與查找。在這里也是同樣的道理,當數據量非常大的時候,若要從這些數據里找出所有的滿足搜索條件的幾乎是不太可能的,將會給服務器帶來極大的負擔。所以我們需要為指定的數據添加一個索引(目錄),在這里是為 Post 創建一個索引,索引的實現細節是我們不需要關心的,我們只關心為哪些字段創建索引,如何指定。

每個索引里面必須有且只能有一個字段為 document=True,這代表 django haystack 和搜索引擎將使用此字段的內容作為索引進行檢索(primary field)。注意,如果使用一個字段設置了document=True,則一般約定此字段名為text,這是在 SearchIndex 類里面一貫的命名,以防止后臺混亂,當然名字你也可以隨便改,不過不建議改。

并且,haystack 提供了 use_template=True 在 text 字段中,這樣就允許我們使用數據模板去建立搜索引擎索引的文件,說得通俗點就是索引里面需要存放一些什么東西,例如 Post 的 title 字段,這樣我們可以通過 title 內容來檢索 Post 數據了。舉個例子,假如你搜索 Python ,那么就可以檢索出 title 中含有 Python 的Post了,怎么樣是不是很簡單?數據模板的路徑為 templates/search/indexes/youapp/<model_name>_text.txt(例如 templates/search/indexes/blog/post_text.txt),其內容為:

文件位置:templates/search/indexes/blog/post_text.txt

{{ object.title }}
{{ object.body }}

這個數據模板的作用是對 Post.title、Post.body 這兩個字段建立索引,當檢索的時候會對這兩個字段做全文檢索匹配,然后將匹配的結果排序后作為搜索結果返回

6. 配置 URL

接下來就是配置 URL,搜索的視圖函數和 URL 模式 django haystack 都已經幫我們寫好了,只需要項目的 urls.py 中包含它:

文件位置:blogproject/urls.py

urlpatterns = [# 其它...path('search/', include('haystack.urls')),
]

另外在此之前我們也為自己寫的搜索視圖配置了 URL,把那個 URL 刪掉,以免沖突:

文件位置:blog/urls.py

# path('search/', views.search, name='search'),

7. 修改搜索表單

修改一下搜索表單,讓它提交數據到 django haystack 搜索視圖對應的 URL:

文件位置:templates/base.html

<form role="search" method="get" id="searchform" action="{% url 'haystack_search' %}"><input type="search" name="q" placeholder="搜索" required><button type="submit"><span class="ion-ios-search-strong"></span></button>
</form>

主要是把表單的 action 屬性改為 {% url ‘haystack_search’ %}

8. 創建搜索結果頁面

haystack_search 視圖函數會將搜索結果傳遞給模板 search/search.html,因此創建這個模板文件,對搜索結果進行渲染:

文件位置:templates/search/search.html


{% extends 'base.html' %}
{% load highlight %}{% block main %}{% if query %}{% for result in page.object_list %}<article class="post post-{{ result.object.pk }}"><header class="entry-header"><h1 class="entry-title"><a href="{{ result.object.get_absolute_url }}">{% highlight result.object.title with query %}</a></h1><div class="entry-meta"><span class="post-category"><a href="{% url 'blog:category' result.object.category.pk %}">{{ result.object.category.name }}</a></span><span class="post-date"><a href="#"><time class="entry-date" datetime="{{ result.object.created_time }}">{{ result.object.created_time }}</time></a></span><span class="post-author"><a href="#">{{ result.object.author }}</a></span><span class="comments-link"><a href="{{ result.object.get_absolute_url }}#comment-area">{{ result.object.comment_set.count }} 評論</a></span><span class="views-count"><ahref="{{ result.object.get_absolute_url }}">{{ result.object.views }} 閱讀</a></span></div></header><div class="entry-content clearfix"><p>{% highlight result.object.body with query %}</p><div class="read-more cl-effect-14"><a href="{{ result.object.get_absolute_url }}" class="more-link">繼續閱讀 <spanclass="meta-nav"></span></a></div></div></article>{% empty %}<div class="no-post">沒有搜索到你想要的結果!</div>{% endfor %}{% if page.has_previous or page.has_next %}<div class="text-center" style="margin-top: 30px">{% if page.has_previous %}<a href="?q={{ query }}&amp;page={{ page.previous_page_number }}">{% endif %}&laquo; Previous{% if page.has_previous %}</a>{% endif %}<span style="margin: 0 10px">|</span>{% if page.has_next %}<a href="?q={{ query }}&amp;page={{ page.next_page_number }}">{% endif %}Next&raquo;{% if page.has_next %}</a>{% endif %}</div>{% endif %}{% else %}請輸入搜索關鍵詞,例如 django{% endif %}
{% endblock main %}

這個模板基本和 blog/index.html 一樣,只是由于 haystack 對搜索結果做了分頁,傳給模板的變量是一個 page 對象,所以我們從 page 中取出這一頁對應的搜索結果,然后對其循環顯示,即 {% for result in page.object_list %}。另外要取得 Post(文章)以顯示文章的數據如標題、正文,需要從 result 的 object 屬性中獲取。query 變量的值即為用戶搜索的關鍵詞。

9. 高亮關鍵詞

注意到百度的搜索結果頁面,含有用戶搜索的關鍵詞的地方都是被標紅的,在 django haystack 中實現這個效果也非常簡單,只需要使用 {% highlight %} 模板標簽即可,其用法如下:

# 1)使用默認值  
{% highlight result.summary with query %}  # 2)這里我們為 {{ result.summary }} 里所有的 {{ query }} 指定了一個<div></div>標簽,并且將class設置為highlight_me_please,這樣就可以自己通過CSS為{{ query }}添加高亮效果了,怎么樣,是不是很科學呢  
{% highlight result.summary with query html_tag "div" css_class "highlight_me_please" %}  # 3)可以 max_length 限制最終{{ result.summary }} 被高亮處理后的長度
{% highlight result.summary with query max_length 40 %}  

在博客文章搜索頁templates/search/search.html中,我們對 title 和 body 做了高亮處理:{% highlight result.object.title with query %},{% highlight result.object.body with query %}。高亮處理的原理其實就是給文本中的關鍵字包上一個 span 標簽并且為其添加 highlighted 樣式(當然你也可以修改這個默認行為,具體參見上邊給出的用法)。因此我們還要給 highlighted 類指定樣式,在 base.html 中添加即可:

文件位置:base.html

<head><title>Black &amp; White</title>...<style>/* 搜索關鍵詞高亮 */span.highlighted {color: red;}</style>...
</head>

10. 建立索引文件

最后一步就是建立索引文件了,運行命令 :

$ docker exec -it hellodjango_blog_tutorial_local python manage.py rebuild_index

就可以建立索引文件了。一切就緒后,就可以嘗試搜索了。但是體驗下來會發現搜索的結果并不是很友好,很多關鍵詞文章中命名存在但搜索結果中卻沒有顯示,原因是 haystack 專門為英文搜索設計,如果使用其默認的搜索引擎分詞器,中文搜索的結果就不是很理想,接下來我們來將它默認的分詞器設置為中文分詞器。

11. 修改搜索引擎為中文分詞

還記得文章開頭編排 elasticsearch 的 Docker 鏡像時,我們將一個 elasticsearch 的中文分詞插件復制到了 elasticsearch 的插件目錄,接下來要做的,就是讓 haystack 在創建索引時,使用指定的插件來對進行分詞并創建索引,具體做法是,首先在 blog 應用下創建一個 elasticsearch2_ik_backend.py,代碼如下:

from haystack.backends.elasticsearch2_backend import Elasticsearch2SearchBackend, Elasticsearch2SearchEngineDEFAULT_FIELD_MAPPING = {'type': 'string', "analyzer": "ik_max_word", "search_analyzer": "ik_smart"}class Elasticsearch2IkSearchBackend(Elasticsearch2SearchBackend):def __init__(self, *args, **kwargs):self.DEFAULT_SETTINGS['settings']['analysis']['analyzer']['ik_analyzer'] = {"type": "custom","tokenizer": "ik_max_word",}super(Elasticsearch2IkSearchBackend, self).__init__(*args, **kwargs)class Elasticsearch2IkSearchEngine(Elasticsearch2SearchEngine):backend = Elasticsearch2IkSearchBackend

這些代碼的作用是,繼承 haystack 默認的 Elasticsearch2SearchBackend 和 Elasticsearch2SearchEngine,覆蓋掉它的一些默認行為,這里主要就是讓 haystack 在創建索引時,使用指定的 ik 分詞器。

由于自定義了搜索引擎,因此在配置文件中將原來指定的 Elasticsearch2SearchEngine 替換為自定義的 Engine:

# 搜索設置
HAYSTACK_CONNECTIONS = {'default': {'ENGINE': 'blog.elasticsearch2_ik_backend.Elasticsearch2IkSearchEngine','URL': '','INDEX_NAME': 'hellodjango_blog_tutorial',},
}
HAYSTACK_SEARCH_RESULTS_PER_PAGE = 10
HAYSTACK_SIGNAL_PROCESSOR = 'haystack.signals.RealtimeSignalProcessor'

由于修改了索引創建方式,因此需要重建一下索引:python manage.py rebuild_index。然后就可以查看搜索結果了,中文搜索體驗是不是好了很多?

12. 防止標題被截斷

haystack 在展示搜索結果時,默認行為是將第一個出現的關鍵詞前的內容截斷,被截掉的部分用省略號代替。對于正文來說,因為內容較多,截斷是合理的,但是對于標題這種較短的內容來說,截斷就沒有必要了。同樣的,我們通過繼承的方式,替換掉 haystack 的默認行為。我們在 blog/utils.py 中繼承 HaystackHighlighter 這個用于高亮搜索關鍵詞的輔助類。

from django.utils.html import strip_tags
from haystack.utils import Highlighter as HaystackHighlighterclass Highlighter(HaystackHighlighter):"""自定義關鍵詞高亮器,不截斷過短的文本(例如文章標題)"""def highlight(self, text_block):self.text_block = strip_tags(text_block)highlight_locations = self.find_highlightable_words()start_offset, end_offset = self.find_window(highlight_locations)if len(text_block) < self.max_length:start_offset = 0return self.render_html(highlight_locations, start_offset, end_offset)

關鍵代碼是:if len(text_block) < self.max_length:,start_offset 是 haystack 根據關鍵詞算出來第一個關鍵詞在文本中出現的位置。max_length 指定了展示結果的最大長度。我們在代碼中做一個判斷,如果文本內容 text_block 沒有超過允許的最大長度,就將 start_offset 設為 0,這樣就從文本的第一個字符開始展示,標題這種短文本就不會被截斷了。

然后設置,讓 haystack 在高亮文本時,使用我們自定義的輔助類:

HAYSTACK_CUSTOM_HIGHLIGHTER = 'blog.utils.Highlighter'

13. 線上發布

以上步驟都是在本地運行調試的,elasticsearch 服務也是在本地的 Docker 容器中運行,接下來在 production.yml 中加入 elasticsearch 服務,就可以發布線上了,配置內容和 local.yml 是一樣的,只是簡單修改一下服務名和容器名等命名:
文件位置:HelloDjango-blog-tutorial\production.yml

  elasticsearch:build:context: .dockerfile: ./compose/production/elasticsearch/Dockerfileimage: hellodjango_blog_tutorial_elasticsearchcontainer_name: hellodjango_blog_tutorial_elasticsearchvolumes:- esdata:/usr/share/elasticsearch/dataports:- "9200:9200"environment:- "ES_JAVA_OPTS=-Xms512m -Xmx512m"ulimits:memlock:soft: -1hard: -1nproc: 65536nofile:soft: 65536hard: 65536

別忘了修改 settings/production.py,修改線上環境 elasticsearch 服務的連接地址:

HAYSTACK_CONNECTIONS['default']['URL'] = 'http://hellodjango_blog_tutorial_elasticsearch:9200/'

這樣就可以直接發布線上了!

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/452122.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/452122.shtml
英文地址,請注明出處:http://en.pswp.cn/news/452122.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Vim和Vi的常用命令

Vim 文本編輯器 1、Vim 和 Vi: 兩者都是多模式編輯器&#xff1b; Vim 是 Vi 升級版&#xff0c;再兼容 Vi 所有指令的同時增加了一些新功能支持&#xff1b; 特點&#xff1a; 語法加亮&#xff1a;使用不同的顏色加亮代碼&#xff1b; 多級撤銷&#xff1a;Vi 只能撤銷一次操…

oracle中 sql語句:start with .. connect by prior.. 用法

前些天發現了一個巨牛的人工智能學習網站&#xff0c;通俗易懂&#xff0c;風趣幽默&#xff0c;忍不住分享一下給大家。點擊跳轉到教程。 我們經常會將一個比較復雜的目錄樹存儲到一個表中。或者將一些部門存儲到一個表中&#xff0c;而這些部門互相有隸屬關系。這個時候你就…

多重繼承和單重繼承

多重繼承&#xff08;Multiple Inheritance, MI&#xff09;指的是一個類別可以同時從多于一個父類繼承行為與特征的功能。與單一繼承相對&#xff0c;單一繼承指一個類別只可以繼承自一個父類。

3分鐘學會SVN:SVN快速上手

選擇SVN客戶端 Windows平臺 TortoiseSVN&#xff1a;也叫烏龜SVN&#xff0c;Windows上最流行的SVN客戶端&#xff0c;安裝后你的右鍵就會多了幾個SVN相關的菜單&#xff0c;非常方便Eclipse插件&#xff1a;在Eclipse中集成SVN插件&#xff0c;適合使用Eclipse開發的用戶&…

flask框架(三):flask配置文件

flask中的配置文件是一個flask.config.Config對象&#xff08;繼承字典&#xff09;,默認配置為&#xff1a;{DEBUG: get_debug_flag(defaultFalse), 是否開啟Debug模式TESTING: False, …

C語言可變參數全解

cstdarg(stdarg.h)可變參數的處理 這個頭文件定義了一些宏&#xff0c;可以通過這些宏來逐個訪問被調函數的沒有名字的參數列表&#xff0c;這些參數的個數 和類型都是不知道的。 一個函數可以通過包含一個逗號和三個點(,...)接收可變數量的額外參數&#xff0c;而不需…

Diango博客--23.單元測試:測試 blog 應用

文章目錄1. 前言2. 搭建測試環境3. 測試模型4. 測試視圖5. 測試模板標簽6. 測試輔助方法和類1. 前言 我們博客功能越來越來完善了&#xff0c;但這也帶來了一個問題&#xff0c;我們不敢輕易地修改已有功能的代碼了&#xff01; 我們怎么知道代碼修改后帶來了預期的效果&…

一般與特殊結構關系 整體與部分結構關系

一般與特殊結構關系又稱為分類結構關系&#xff0c;是“is a”關系。 例如&#xff1a;飛機與交通工具都是類&#xff0c;飛機是一種特殊的交通工具。他們之間是“is a”關系。 上層類體現一般性和共性&#xff0c;下層類體現特殊性和具體性。 用這種結構關系來描述現實世界…

簡單版:帶干擾線的圖形驗證碼生成

前些天發現了一個巨牛的人工智能學習網站&#xff0c;通俗易懂&#xff0c;風趣幽默&#xff0c;忍不住分享一下給大家。點擊跳轉到教程。 1.生成工具類; import java.awt.Color; import java.awt.Font; import java.awt.Graphics; import java.awt.image.BufferedImage; im…

圖片格式轉換工具與方法

2019獨角獸企業重金招聘Python工程師標準>>> 使用ffmpeg進行格式轉換 1.jpg 轉 I420 ffmpeg -i 001.jpg -pix_fmt yuv420p 001_I420_fromJPG.yuv 2.png 轉 I420 ffmpeg -i 222.png -pix_fmt yuv420p 222_I420_fromPNG.yuv 3.bmp 轉 I420 ffmpeg -i xxx.bmp -pix_fmt…

Diango博客--24.單元測試:測試評論應用

文章目錄1. 前言2. 數據基類3.測試 Comment Model4. 測試視圖函數5. 測試模板標簽1. 前言 comments應用的測試和blog應用測試的套路是一樣的。 先來建立測試文件的目錄結構。首先在 comments 應用的目錄下建立一個名為 tests 的 Python 包&#xff0c;然后刪除 comments 應用…

面向對象設計使用語言選擇

面向對象設計的結果既可以用面向對象語言、也可以用非面向對象語言實現。 使用面向對象語言時&#xff0c;由于語言本身充分支持面向對象概念的實現&#xff0c;因此&#xff0c;編譯程序可以自動把面向對象概念映射到目標程序中。 使用非面向對象語言編寫面向對象程序&#xf…

結合shiro 的圖形驗證碼生成

前些天發現了一個巨牛的人工智能學習網站&#xff0c;通俗易懂&#xff0c;風趣幽默&#xff0c;忍不住分享一下給大家。點擊跳轉到教程。 在做用戶登錄功能時&#xff0c;很多時候都需要驗證碼支持&#xff0c;驗證碼的目的是為了防止機器人模擬真實用戶登錄而惡意訪問&#…

利用C語言實現計算機圖像處理的方法

1&#xff0e;圖像平移 圖像平移只是改變圖像在屏幕上的位置&#xff0c;圖像本身并不發生變化。假設原圖像區域左上角坐標為(x0, y0)&#xff0c;右下角坐標為(x1, y1)&#xff0c;將圖像分別沿x和y軸平移dx和dy&#xff0c;則新圖像的左上角坐標為(x0 &#xff0b; dx, y0 &a…

E24- please install the following Perl modules before executing ./mysql_install_db

2019獨角獸企業重金招聘Python工程師標準>>> [roott-cet7 scripts]# ./mysql_install_db --basedir/usr/local/mysql/ --datadir/app/data/ --usermysql FATAL ERROR: please install the following Perl modules before executing ./mysql_install_db: Data::Dumpe…

SpringMVC異常報406 (Not Acceptable)的解決辦法

使用SpsringMVC&#xff0c;使用restEasy調試&#xff0c;controller請求設置如下&#xff1a; Java代碼 RequestMapping(value"/list",methodRequestMethod.GET,producesMediaType.APPLICATION_JSON_VALUE) ResponseBody public List<EditTimeout> list()…

Diango博客--25.使用Coverage統計測試覆蓋率

文章目錄1. 前言2. 安裝 Coverage3. 簡單配置 Coverage4. 運行 Coverage5. 完善 Coverage 配置6. 生成 HTML 報告7. 完善單元測試1. 前言 我們完成了對 blog 應用和 comment 應用這兩個核心 app 的測試。現在我們想知道的是究竟測試效果怎么樣呢&#xff1f;測試充分嗎&#x…

面向對象語言的優點

1.一致的表達方法 從前面章節的講述中可以知道&#xff0c;面向對象開發基于不隨時間變化的、一致的表示方法。這種表示方法應該從問題域到OOA&#xff0c;從OOA到OOD&#xff0c;最后從OOD到面向對象編程(OOP)&#xff0c;始終穩定不變。 一致的表示方法&#xff1a; 既有利…

最好的英文詞典

辭典對于學外語的作用&#xff0c;怎么強調也不過分。經常接觸英語的人都知道&#xff0c;遇到生詞不可怕&#xff0c;可怕的是遇到認識的單詞&#xff0c;又不明白這句話什么意思。這個時候&#xff0c;辭典的作用就發揮出來了。 今天一位朋友問我一句英文的意思&#xff0c;…

oracle用戶創建及權限設置

權限&#xff1a; create session create table unlimited tablespace connect resource dba 例&#xff1a; #sqlplus /nolog SQL> conn / as sysdba; SQL>create user username identified by password SQL> grant dba to username; SQL> conn username/password…