性久久久久久,性色av浪潮av色欲av,国产日韩精品在线观看,亚洲色成人网一二三区

歡迎您光臨深圳塔燈網(wǎng)絡(luò)科技有限公司!
電話圖標(biāo) 余先生:13699882642

網(wǎng)站百科

為您解碼網(wǎng)站建設(shè)的點(diǎn)點(diǎn)滴滴

第十三章 上線

發(fā)表日期:2017-05 文章編輯:小燈 瀏覽次數(shù):2293

13 上線

上一章中,你為你的項(xiàng)目創(chuàng)建了RESTful API。在本章中,你會(huì)學(xué)習(xí)以下知識(shí)點(diǎn):

  • 配置一個(gè)生產(chǎn)環(huán)境
  • 創(chuàng)建一個(gè)自定義的中間件
  • 實(shí)現(xiàn)自定義的管理命令

13.1 在生產(chǎn)環(huán)境上線

是時(shí)候把你的Django項(xiàng)目部署到生產(chǎn)環(huán)境了。我們將按以下步驟上線我們的項(xiàng)目:

  1. 為生產(chǎn)環(huán)境配置項(xiàng)目設(shè)置。
  2. 使用PostgreSQL數(shù)據(jù)庫(kù)。
  3. 使用uWSGINgnix設(shè)置一個(gè)web服務(wù)器。
  4. 為靜態(tài)資源提供服務(wù)。
  5. 用SSL保護(hù)我們的網(wǎng)站。

13.1.1 為多個(gè)環(huán)境管理設(shè)置

在實(shí)際項(xiàng)目中,你可能需要處理多個(gè)環(huán)境。你最少會(huì)有一個(gè)本地環(huán)境和一個(gè)生產(chǎn)環(huán)境,但是很可能還有別的環(huán)境。有些項(xiàng)目設(shè)置是所有環(huán)境通用的,有些可能需要被每個(gè)環(huán)境覆蓋。讓我們?yōu)槎鄠€(gè)環(huán)境配置項(xiàng)目設(shè)置,同時(shí)保持項(xiàng)目的良好組織。

educa項(xiàng)目目錄中創(chuàng)建settings/目錄。把項(xiàng)目的settings.py文件移動(dòng)到settings/目錄中,并重命名為base.py,然后在新目錄中創(chuàng)建以下文件結(jié)構(gòu):

settings/ __init__.py base.py local.py pro.py 

這些文件分別是:

  • base.py:包括通用和默認(rèn)設(shè)置的基礎(chǔ)設(shè)置文件
  • local.py:你本地環(huán)境的自定義設(shè)置
  • pro.py:生產(chǎn)環(huán)境的自定義設(shè)置

編輯settings/base.py文件,找到這一行代碼:

BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) 

替換為下面這一行代碼:

BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(os.path.join(__file__, os.pardir)))) 

我們已經(jīng)把設(shè)置文件移動(dòng)到了低一級(jí)的目錄中,所以我們需要BASE_DIR正確的指向父目錄。我們使用os.pardir指向父目錄。

編輯settings/local.py文件,并添加以下代碼:

from .base import *DEBUG = TrueDATABASES = { 'default': { 'ENGINE': 'django.db.backends.sqlite3', 'NAME': os.path.join(BASE_DIR, 'db.sqlite3'), } } 

這是我們本地環(huán)境的設(shè)置文件。我們導(dǎo)入base.py文件中定義的所有設(shè)置,只為這個(gè)生產(chǎn)環(huán)境定義特定設(shè)置。我們從base.py文件中拷貝了DEBUGDATABASES設(shè)置,因?yàn)槊總€(gè)環(huán)境會(huì)設(shè)置這些選項(xiàng)。你可以從base.py文件中移除DEBUGDATABASES設(shè)置。

編輯settings/pro.py文件,并添加以下代碼:

from .base import *DEBUG = FalseADMINS = { ('Antonio M', 'email@mydomain.com'), }ALLOWED_HOSTS = ['educaproject.com', 'www.educaproject.com']DATABASES = { 'default': {} } 

這些是生產(chǎn)環(huán)境的設(shè)置。它們分別是:

  • DEBUG:設(shè)置DEBUGFalse對(duì)任何生產(chǎn)環(huán)境都是強(qiáng)制的。不這么做會(huì)導(dǎo)致追蹤信息和敏感的配置數(shù)據(jù)暴露給每一個(gè)人。
  • ADMINS:當(dāng)DEBUGFalse,并且一個(gè)視圖拋出異常時(shí),所有信息會(huì)通過(guò)郵件發(fā)送給ADMINS設(shè)置中列出的所有人。確保用你自己的信息替換上面的name/e-mail元組。
  • ALLOWED_HOST:因?yàn)?code>DEBUG為False,Django只允許這個(gè)列表中列出的主機(jī)為應(yīng)用提供服務(wù)。這是一個(gè)安全措施。我們包括了educaproject.comwww.educaproject.com域名,我們的網(wǎng)站會(huì)使用這兩個(gè)域名。
  • DATABASES:我們保留這個(gè)設(shè)置為空。我們將在下面討論生產(chǎn)環(huán)境的數(shù)據(jù)庫(kù)設(shè)置。

處理多個(gè)環(huán)境時(shí),創(chuàng)建一個(gè)基礎(chǔ)的設(shè)置文件,并為每個(gè)環(huán)境創(chuàng)建一個(gè)設(shè)置文件。環(huán)境設(shè)置文件應(yīng)用從通用設(shè)置繼承,并覆寫(xiě)環(huán)境特定設(shè)置。

我們已經(jīng)把項(xiàng)目設(shè)置從默認(rèn)的settings.py文件放到了不同位置。除非你指定使用的設(shè)置模塊,否則不能用manage.py工具執(zhí)行任何命令。在終端執(zhí)行管理命令時(shí),你需要添加--settings標(biāo)記,或者設(shè)置DJANGO_SETTINGS_MODULE環(huán)境變量。打開(kāi)終端執(zhí)行以下命令:

export DJANGO_SETTINGS_MODULE=educa.settings.pro 

這會(huì)為當(dāng)前終端會(huì)話是設(shè)置DJANGO_SETTINGS_MODULE環(huán)境變量。如果你不想為每個(gè)新終端都執(zhí)行這個(gè)命令,可以在.bashrc.bash_profile文件中,把這個(gè)命令添加到你的終端配置。如果你不想設(shè)置這個(gè)變量,則必須使用--settings標(biāo)記運(yùn)行管理命令,比如:

python manage.py migrate --settings=educa.settings.pro 

現(xiàn)在你已經(jīng)成功的為多個(gè)環(huán)境組織好了設(shè)置。

13.1.2 安裝PostgreSQL

在本書(shū)中,我們一直使用SQLite數(shù)據(jù)庫(kù)。它的設(shè)置簡(jiǎn)單快捷,但對(duì)于生產(chǎn)環(huán)境,你需要一個(gè)更強(qiáng)大的數(shù)據(jù)庫(kù),比如PostgreSQL,MySQL或者Oracle。我們將在生產(chǎn)環(huán)境使用PostgreSQL。因?yàn)镻ostgreSQL提供的特性和性能,所以它是Django的推薦數(shù)據(jù)庫(kù)。Django還自帶django.contrib.postgres包,允許你利用PostgreSQL的特定特性。你可以在這里閱讀更多關(guān)于這個(gè)模塊的信息。

如果你正在使用Linux,使用以下命令安裝PostgreSQL的依賴(lài):

sudo apt-get install libpq-dev python-dev 

然后使用以下命令安裝PostgreSQL:

sudo apt-get install postgresql postgresql-contrib 

如果你正在使用Mac OS X或者Windows,你可以在這里下載PostgreSQL。

讓我們創(chuàng)建一個(gè)PostgreSQL用戶。打開(kāi)終端,并執(zhí)行以下命令:

su postgres createuser -dP educa 

會(huì)提示你輸入密碼和給予這個(gè)用戶的權(quán)限。輸入密碼和權(quán)限,然后使用以下命令創(chuàng)建一個(gè)新的數(shù)據(jù)庫(kù):

createdb -E utf8 -U educa educa 

然后編輯settings/pro.py文件,并修改DATABASES設(shè)置:

DATABASES = { 'default': { 'ENGINE': 'django.db.backends.postgresql_psycopg2', 'NAME': 'educa', 'USER': 'educa', 'PASSWORD': '****', } } 

用你創(chuàng)建的數(shù)據(jù)庫(kù)名和用戶憑證替換上面的數(shù)據(jù)?,F(xiàn)在新數(shù)據(jù)庫(kù)是空的。執(zhí)行以下命令應(yīng)用所有數(shù)據(jù)庫(kù)遷移:

python manage.py migrate 

最后使用以下命令創(chuàng)建一個(gè)超級(jí)用戶:

python manage.py createsuperuser 

13.1.3 檢查你的項(xiàng)目

Django包括check命令,可以在任何時(shí)候檢查你的項(xiàng)目。這個(gè)命令檢查Django項(xiàng)目中安裝的應(yīng)用,并輸出所有錯(cuò)誤或警告。如果你包括了--deploy選項(xiàng),則只會(huì)觸發(fā)生成環(huán)境相關(guān)的額外檢查。打開(kāi)終端,運(yùn)行以下命令執(zhí)行一次檢查:

python manage.py check --deploy 

你會(huì)看到?jīng)]有錯(cuò)誤,但是有幾個(gè)警告的輸出。這意味著檢查成功了,但你應(yīng)該查看警告,看看是否可以做一些工作,讓你的項(xiàng)目在生產(chǎn)環(huán)境上是安全的。我們不會(huì)深入其中,你需要記住,在生產(chǎn)環(huán)境中使用之前,你應(yīng)該檢查項(xiàng)目所有相關(guān)的問(wèn)題。

13.2 通過(guò)WSGI為Django提供服務(wù)

Django的主要部署平臺(tái)是WSGI。WSGI是Web Server Gateway Interface的縮寫(xiě),它是在網(wǎng)絡(luò)上為Python應(yīng)用提供服務(wù)的標(biāo)準(zhǔn)。

當(dāng)你使用startproject命令創(chuàng)建一個(gè)新項(xiàng)目時(shí),Django會(huì)在項(xiàng)目目錄中創(chuàng)建一個(gè)wsgi.py文件。這個(gè)文件包含一個(gè)WSGI應(yīng)用的可調(diào)用對(duì)象,它是你應(yīng)用的訪問(wèn)點(diǎn)。使用Django開(kāi)發(fā)服務(wù)器運(yùn)行你的項(xiàng)目,以及在生產(chǎn)環(huán)境中用你選擇的服務(wù)器部署應(yīng)用都會(huì)使用WSGI。

你可以在這里進(jìn)一步學(xué)習(xí)WSGI。

13.2.1 安裝uWSGI

在這本書(shū)中,你一直使用Django開(kāi)發(fā)服務(wù)器在本地環(huán)境運(yùn)行項(xiàng)目。但是你需要一個(gè)實(shí)際的Web服務(wù)器在生產(chǎn)環(huán)境部署你的應(yīng)用。

uWSGI是一個(gè)非??焖俚腜ython應(yīng)用服務(wù)器。它使用WSGI規(guī)范與你的Python應(yīng)用通信。uWSGI把Web請(qǐng)求轉(zhuǎn)換為Django項(xiàng)目可用處理的格式。

使用以下命令安裝uWSGI

pip install uwsgi 

如果你正在使用Mac OS X,你可以使用brew install uwsgi命令安裝uWSGI。如果你想在Windows上安裝uWSGI,則需要Cygwin。但是推薦你在基于Unix的環(huán)境中使用uWSGI。

13.2.2 配置uWSGI

你可以從命令行中啟動(dòng)uWSGI。打開(kāi)終端,在educa項(xiàng)目目錄中執(zhí)行以下命令:

uwsgi --module=educa.wsgi:application \ --env=DJANGO_SETTINGS_MODULE=educa.settings.pro \ --http=127.0.0.1:80 \ --uid=1000 \ --virtualenv=/home/zenx/env/educa/ 

如果你沒(méi)有權(quán)限,則需要在命令前加上sudo。

通過(guò)這個(gè)命令,我們用以下選項(xiàng)在本地運(yùn)行uWSGI

  • 我們使用educa.wsgi:application作為WSGI的可調(diào)用對(duì)象。
  • 我們?yōu)樯a(chǎn)環(huán)境加載設(shè)置。
  • 我們使用我們的虛擬環(huán)境。用你的實(shí)際虛擬環(huán)境目錄替換virtualenv選項(xiàng)的路徑。如果你沒(méi)有使用虛擬環(huán)境,則跳過(guò)這個(gè)選項(xiàng)。

如果你沒(méi)有在項(xiàng)目目錄下運(yùn)行命令,則需要用你的項(xiàng)目目錄包括--chdir=/path/to/educa/選項(xiàng)。

在瀏覽器中打開(kāi)http://127.0.0.1:80/。你會(huì)看到?jīng)]有加載CSS或者圖片的HTML。這是有道理的,因?yàn)槲覀冞€沒(méi)有配置uWSGI為靜態(tài)文件提供服務(wù)。

uWSGI允許你在.ini文件中定義自定義配置。它比在命令行中傳遞選項(xiàng)更方便。在主educa/目錄下創(chuàng)建以下文件結(jié)構(gòu):

config/ uwsgi.ini 

編輯uwsgi.ini文件,添加以下代碼:

[uwsgi] # variables projectname = educa base = /home/zenx/educa# configuration master = true virtualenv = /home/zenx/env/%(projectname) pythonpath = %(base) chdir = %(base) env = DJANGO_SETTINGS_MODULE=%(projectname).settings.pro module = educa.wsgi:application socket = /tmp/%(projectname).sock 

我們定義了以下變量:

  • projectname:你的Django項(xiàng)目名稱(chēng),這里是educa
  • baseeduca項(xiàng)目的絕對(duì)路徑。用你的絕對(duì)路徑替換它。

還有一些會(huì)在uWSGI選項(xiàng)中使用的自定義變量。你可以定義任意變量,只要它跟uWSGI選項(xiàng)名不同就行。我們?cè)O(shè)置了以下選項(xiàng):

  • master:?jiǎn)⒂弥鬟M(jìn)程。
  • virtualenv:你的虛擬環(huán)境路徑。用響應(yīng)的路徑替換它。
  • pythonpath:添加到Python路徑的路徑。
  • chdir:項(xiàng)目目錄的路徑,加載應(yīng)用之前,uWSGI改變到這個(gè)目錄。
  • env:環(huán)境變量。我們包括了DJANGO_SETTINGS_MODULE變量,指向生產(chǎn)環(huán)境的設(shè)置。
  • module:使用的WSGI模塊。我們把它設(shè)置為application可調(diào)用對(duì)象,它包含在項(xiàng)目的wsgi模塊中。
  • socket:綁定到服務(wù)器的UNIX/TCP套接字。

socket選項(xiàng)用于與第三方路由(比如Nginx)通信,而http選項(xiàng)用于uWGSI接收傳入的HTTP請(qǐng)求,并自己進(jìn)行路由。因?yàn)槲覀儗⑴渲肗ginx作為Web服務(wù)器,并通過(guò)套接字與uWSGI通信,所以我們將使用套接字運(yùn)行uWSGI。

你可以在這里找到所有可用的uWSGI選項(xiàng)列表。

現(xiàn)在你可以使用自定義配置運(yùn)行uWSGI

uwsgi --ini config/uwsgi.ini 

因?yàn)?code>uWSGI通過(guò)套接字運(yùn)行,所以你現(xiàn)在不能在瀏覽器中訪問(wèn)uWSGI實(shí)例。讓我們完成生產(chǎn)環(huán)境。

13.2.3 安裝Nginx

當(dāng)你為一個(gè)網(wǎng)站提供服務(wù)時(shí),你必須為動(dòng)態(tài)內(nèi)容提供服務(wù),同時(shí)還需要為靜態(tài)文件,比如CSS,JavaScript文件和圖片提供服務(wù)。雖然uWSGI可以為靜態(tài)文件提供服務(wù),但它會(huì)在HTTP請(qǐng)求上增加不必要的開(kāi)銷(xiāo)。因此,推薦在uWSGI之前設(shè)置一個(gè)Web服務(wù)器(比如Nginx),為靜態(tài)文件提供服務(wù)。

Nginx是一個(gè)專(zhuān)注于高并發(fā),高性能和低內(nèi)存使用的Web服務(wù)器。Nginx還可以充當(dāng)反向代理,接收HTTP請(qǐng)求,并把它們路由到不同的后臺(tái)。通常情況下,你會(huì)在前端使用一個(gè)Web服務(wù)器(比如Nginx),高效快速的為靜態(tài)文件提供服務(wù),并且把動(dòng)態(tài)請(qǐng)求轉(zhuǎn)發(fā)到uWSGI的工作線程。通過(guò)使用Nginx,你還可以應(yīng)用規(guī)則,并從它的反向代理功能中獲益。

使用以下命令安裝Nginx:

sudo apt-get install nginx 

如果你正在使用Mac OS X,你可以使用brew install nginx命令安裝Nginx。你可以在這里找到Windows的二進(jìn)制版本。

13.2.4 生產(chǎn)環(huán)境

下圖展示了我們最終的生產(chǎn)環(huán)境:

當(dāng)客戶端瀏覽器發(fā)起一個(gè)HTTP請(qǐng)求時(shí),會(huì)發(fā)生以下事情:

  1. Nginx接收HTTP請(qǐng)求。
  2. 如果請(qǐng)求的是靜態(tài)文件,則Nginx直接為靜態(tài)文件提供服務(wù)。如果請(qǐng)求的是動(dòng)態(tài)頁(yè)面,則Nginx通過(guò)套接字把請(qǐng)求轉(zhuǎn)發(fā)給uWSGI。
  3. uWSGI把請(qǐng)求傳遞給Django處理。返回的HTTP響應(yīng)傳遞回Nginx,然后再返回到客戶端瀏覽器。

13.2.5 配置Nginx

config/目錄中創(chuàng)建nginx.conf文件,并添加以下代碼:

# the upstream component nginx needs to connect to upstream educa { server unix:///tmp/educa.sock; }server { listen 80; server_name www.educaproject.com educaproject.com;location / { include /etc/nginx/uwsgi_params; uwsgi_pass educa; } } 

這是Nginx的基礎(chǔ)配置。我們?cè)O(shè)置了一個(gè)名為educa的上游(upstream),指向uWSGI創(chuàng)建的套接字。我們使用server指令,并添加以下配置:

  1. 我們告訴Nginx監(jiān)聽(tīng)80端口。
  2. 我們?cè)O(shè)置服務(wù)名為www.educaproject.comeducaproject.com。Nginx會(huì)為來(lái)自這兩個(gè)域名的請(qǐng)求服務(wù)。
  3. 最后,我們指定/路徑下的所有請(qǐng)求都路由到educa套接字(uWSGI)。我們還包括了Nginx自帶的默認(rèn)uWSGI配置參數(shù)。

你可以在這里閱讀Nginx文檔。主要的Nginx配置文件位于/etc/nginx/nginx.conf。它包括了/etc/nginx/sites-enabled/下找到的所有配置文件。要讓Nginx加載你的自定義配置文件,需要如下創(chuàng)建一個(gè)符號(hào)鏈接:

sudo ln -s /home/zenx/educa/config/nginx.conf /etc/nginx/sites-enabled/educa.conf 

用你項(xiàng)目的絕對(duì)路徑替換/home/zenx/educa/。然后打開(kāi)終端啟動(dòng)uWSGI

uwsgi --ini config/uwsgi.ini 

打開(kāi)第二個(gè)終端,用以下命令啟動(dòng)Nginx:

service nginx start 

因?yàn)槲覀冋谑褂煤?jiǎn)單的主機(jī)名,所以需要把它重定向到本機(jī)。編輯你的/etc/hosts文件,添加下面兩行:

127.0.0.1 educaproject.com 127.0.0.1 www.educaproject.com 

這樣,我們把兩個(gè)主機(jī)名路由到我們的本地服務(wù)器。在生產(chǎn)環(huán)境中你不需要這么用,因?yàn)槟銜?huì)在域名的DNS配置中把主機(jī)名指向你的服務(wù)器。

在瀏覽器中打開(kāi)http://educaproject.com。你可以看到你的網(wǎng)站,仍然沒(méi)有加載任何靜態(tài)資源。我們的生產(chǎn)環(huán)境馬上就好了。

13.2.6 為靜態(tài)資源和多媒體資源提供服務(wù)

為了最好的性能,我們將直接使用Nginx為靜態(tài)資源提供服務(wù)。

編輯settings/base.py文件,并添加以下代碼:

STATIC_URL = '/static/' STATIC_ROOT = os.path.join(BASE_DIR, 'static/') 

我們需要用Django導(dǎo)出靜態(tài)資源。collectstatic命令從所有應(yīng)用中拷貝靜態(tài)文件,并把它們存儲(chǔ)到STATIC_ROOT目錄中。打開(kāi)終端執(zhí)行以下命令:

python manage.py collectstatic 

你會(huì)看到以下輸出:

You have requested to collect static files at the destination location as specified in your settings:/educa/staticThis will overwrite existing files! Are you sure you want to do this? 

輸入yes讓Django拷貝這些文件。你會(huì)看到以下輸出:

78 static files copied to /educa/static 

現(xiàn)在編輯config/nginx.conf文件,并在server指令中添加以下代碼:

location /static/ { alias /home/zenx/educa/static/; } location /media/ { alias /home/zenx/educa/media/; } 

記得把/home/zenx/educa/路徑替換為你項(xiàng)目目錄的絕對(duì)路徑。這些指令告訴Nginx,直接在/static//media/路徑下為靜態(tài)資源提供服務(wù)。

使用以下命令重新加載Nginx的配置:

server nginx reload 

在瀏覽器中打開(kāi)http://educaproject.com/?,F(xiàn)在你可以看到靜態(tài)文件了。我們成功的配置了Nginx來(lái)提供靜態(tài)文件。

13.3 使用SSL保護(hù)鏈接

SSL協(xié)議(Secure Sockets Layer)通過(guò)安全連接成為了為網(wǎng)站提供服務(wù)的標(biāo)準(zhǔn)。強(qiáng)烈鼓勵(lì)你在HTTPS下為網(wǎng)站提供服務(wù)。我們將在Nginx中配置一個(gè)SSL證書(shū),安全的為我們網(wǎng)站提供服務(wù)。

13.3.1 創(chuàng)建SSL證書(shū)

educa項(xiàng)目目錄中創(chuàng)建ssl目錄。然后使用以下命令生成一個(gè)SSL證書(shū):

sudo openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout ssl/educa.key -out ssl/educa.crt 

我們生成一個(gè)私有key和一個(gè)有效期是1年的2048個(gè)字節(jié)的證書(shū)。你將被要求輸入以下信息:

Country Name (2 letter code) [AU]: State or Province Name (full name) [Some-State]: Locality Name (eg, city) []: Madrid Organization Name (eg, company) [Internet Widgits Pty Ltd]: Zenx IT Organizational Unit Name (eg, section) []: Common Name (e.g. server FQDN or YOUR name) []: educaproject.com Email Address []: email@domain.com 

你可以用自己的信息填寫(xiě)要求的數(shù)據(jù)。最重要的字段是Common Name。你必須制定證書(shū)的域名。我們將使用educaproject.com。

這會(huì)在ssl/目錄中生成educa.key的私有key和實(shí)際證書(shū)educa.crt文件。

13.3.2 配置Nginx使用SSL

編輯nginx.conf文件,并修改server指令,讓它包括以下SSL指令:

server { listen 80; listen 443 ssl; ssl_certificate /home/zenx/educa/ssl/educa.crt; ssl_certificate_key /home/zenx/educa/ssl/educa.key; server_name www.educaproject.com educaproject.com; # ... 

現(xiàn)在我們的服務(wù)器在80端口監(jiān)聽(tīng)HTTP,在443端口監(jiān)聽(tīng)HTTPS。我們用ssl_certificate制定SSL證書(shū),用ssl_certificate_key制定證書(shū)key。

使用以下命令重啟Nginx:

sudo service nginx restart 

Nginx將會(huì)加載新的配置。在瀏覽器中打開(kāi)http://educaproject.com。你會(huì)看到一個(gè)類(lèi)似這樣的靜態(tài)消息:

不同的瀏覽器,這個(gè)消息可能會(huì)不同。它警告你,你的網(wǎng)站沒(méi)有使用受信任的證書(shū);瀏覽器不能驗(yàn)證網(wǎng)站的身份。這是因?yàn)槲覀兒炇鹆俗约旱淖C書(shū),而不是從受信任的認(rèn)證機(jī)構(gòu)獲得證書(shū)。當(dāng)你擁有真正的域名時(shí),你可以申請(qǐng)受信任的CA為其頒發(fā)SSL證書(shū),以便瀏覽器可以驗(yàn)證其身份。

如果你想為真正域名獲得受信任的證書(shū),你可以參數(shù)Linux Foundation創(chuàng)建的Let's Encrypt項(xiàng)目。這是一個(gè)協(xié)作項(xiàng)目,目的是免費(fèi)的簡(jiǎn)化獲取和更新受信任的SSL證書(shū)。你可以在這里閱讀更多信息。

點(diǎn)擊Add Exception按鈕,讓瀏覽器知道你信任這個(gè)證書(shū)。你會(huì)看到瀏覽器在URL旁顯示一個(gè)鎖的圖標(biāo),如下圖所示:

如果你點(diǎn)擊鎖圖標(biāo),則會(huì)顯示SSL證書(shū)的詳情。

13.3.3 為SSL配置我們的項(xiàng)目

Django包括一些SSL的特定設(shè)置。編輯settings/pro.py設(shè)置文件,添加以下代碼:

SECURE_SSL_REDIRECT = True CSRF_COOKIE_SECURE = True 

這些設(shè)置分別是:

  • SECURE_SSL_REDIRECT:HTTP請(qǐng)求是否必須重定義到HTTPS請(qǐng)求
  • CSRF_COOKIE_SECURE:這必須為跨站點(diǎn)請(qǐng)求保護(hù)設(shè)置為建立一個(gè)安全的cookie

非常棒!你已經(jīng)配置了一個(gè)生產(chǎn)環(huán)境,它會(huì)為你的項(xiàng)目提供高性能的服務(wù)。

13.4 創(chuàng)建自定義的中間件

你已經(jīng)了解了MIDDLEWARE設(shè)置,其中包括項(xiàng)目的中間件。一個(gè)中間件是一個(gè)類(lèi),其中包括一些在全局執(zhí)行的特定方法。你可以把它看成一個(gè)低級(jí)別的插件系統(tǒng),允許你實(shí)現(xiàn)在請(qǐng)求或響應(yīng)過(guò)程中執(zhí)行的鉤子。每個(gè)中間件負(fù)責(zé)會(huì)在所有請(qǐng)求或響應(yīng)中執(zhí)行的一些特定操作。

避免在中間件中添加開(kāi)銷(xiāo)昂貴的處理,因?yàn)樗鼈優(yōu)樵诿總€(gè)請(qǐng)求中執(zhí)行。

當(dāng)收到一個(gè)HTTP請(qǐng)求時(shí),中間件會(huì)以MIDDLEWARE設(shè)置中的出現(xiàn)順序執(zhí)行。當(dāng)一個(gè)HTTP響應(yīng)由Django生成時(shí),中間件的方法會(huì)逆序執(zhí)行。

下圖展示了請(qǐng)求和響應(yīng)階段時(shí),中間件方法的執(zhí)行順序。它還展示了可能被調(diào)用的中間件方法:

在請(qǐng)求階段,會(huì)執(zhí)行中間件的以下方法:

  1. process_request(request):在Django決定執(zhí)行哪個(gè)視圖之前,在每個(gè)請(qǐng)求上調(diào)用。request是一個(gè)HttpRequest實(shí)例。
  2. process_view(request, view_func, view_args, view_kwargs):在Django調(diào)用視圖之前調(diào)用。它可以訪問(wèn)視圖函數(shù)及其收到的參數(shù)

在響應(yīng)階段,會(huì)執(zhí)行中間件的以下方法:

  1. process_exception(request, exception):只有視圖函數(shù)拋出Exception異常時(shí)才會(huì)調(diào)用。
  2. process_template_response(request, response):視圖執(zhí)行完成后調(diào)用,只有當(dāng)response對(duì)象有render()方法時(shí)才調(diào)用(比如它是TemplateResponse或者等價(jià)對(duì)象)
  3. process_response(request, response):響應(yīng)返回到瀏覽器之前,在所有響應(yīng)上調(diào)用。

因?yàn)橹虚g件可以依賴(lài)之前已經(jīng)執(zhí)行的其它中間件方法在請(qǐng)求中設(shè)置的數(shù)據(jù),所以MIDDLEWARE設(shè)置中的順序很重要。請(qǐng)注意,即使因?yàn)榍耙粋€(gè)中間件返回了HTTP響應(yīng),導(dǎo)致process_request()process_view()被跳過(guò),中間件的process_response()方法也會(huì)被調(diào)用。這意味著process_response()不能依賴(lài)于請(qǐng)求階段設(shè)置的數(shù)據(jù)。如果一個(gè)異常被某個(gè)中間件處理,并返回了一個(gè)響應(yīng),則之前的中間件類(lèi)不會(huì)被調(diào)用。

當(dāng)添加新的中間件到MIDDLEWARE設(shè)置中時(shí),確保把它放在了正確的位置。在請(qǐng)求階段,中間件方法按設(shè)置中的出現(xiàn)順序執(zhí)行,響應(yīng)階段則是逆序執(zhí)行。

你可以在這里查看更多關(guān)于中間件的信息。

我們將創(chuàng)建一個(gè)自定義的中間件,允許通過(guò)自定義子域名訪問(wèn)課程。每個(gè)課程詳情視圖的URL(比如http://educaproject.com/courses/django/)也可以通過(guò)子域名(用課程的slug字段構(gòu)建)訪問(wèn),比如http://django.educaproject.com/。

13.4.1 創(chuàng)建子域名中間件

中間件可以位于項(xiàng)目的任何地方。但是,推薦的方式是在應(yīng)用目錄中創(chuàng)建一個(gè)middleware.py文件。

courses應(yīng)用目錄中創(chuàng)建middleware.py文件,并添加以下代碼:

from django.core.urlresolvers import reverse from django.shortcuts import get_object_or_404, redirect from .models import Courseclass SubdomainCourseMiddleware: def process_request(self, request): host_parts = request.get_host().split('.') if len(host_parts) > 2 and host_parts[0] != 'www': # get course for the given subdomain course = get_object_or_404(Course, slug=host_parts[0]) course_url = reverse('course_detail', args=[course.slug]) # redirect current request to the course_detail view url = '{}://{}{}'.format( request.scheme, '.'.join(host_parts[1:]), course_url ) return redirect(url) 

我們創(chuàng)建了一個(gè)實(shí)現(xiàn)了process_request()的中間件。當(dāng)收到HTTP請(qǐng)求時(shí),我們執(zhí)行以下任務(wù):

  1. 我們獲得請(qǐng)求中使用的主機(jī)名,并把它拆分為多個(gè)部分。比如,如果用戶訪問(wèn)的是mycourse.educaproject.com,則會(huì)生成['mycourse', 'educaproject', 'com']列表。
  2. 通過(guò)檢查拆分后是否生成兩個(gè)以上的元素,我們核實(shí)包括子域名的主機(jī)名。如果主機(jī)名包括子域名,并且它不是www,則嘗試使用子域名提供的slug獲得課程。
  3. 如果沒(méi)有找到課程,我們拋出Http 404異常。否則,我們使用主域名重定向到課程詳情的URL。

編輯項(xiàng)目的settings/base.py文件,在MIDDLEWARE設(shè)置底部添加courses.middleware.SubdomainCourseMiddleware

MIDDLEWARE = [ # ... 'courses.middleware.SubdomainCourseMiddleware', ] 

現(xiàn)在我們的中間件會(huì)在每個(gè)請(qǐng)求上執(zhí)行。

13.4.2 使用Nginx為多個(gè)子域名服務(wù)

我們需要Nginx為帶任意可能子域名的我們的網(wǎng)站提供服務(wù)。編輯config/nginx.conf文件,找到這一行代碼:

server_name www.educaproject.com educaproject.com; 

替換為下面這一行代碼:

server_name *.educaproject.com educaproject.com; 

通過(guò)使用星號(hào),這條規(guī)則會(huì)應(yīng)用與educaproject.com的所有子域名。為了在本地測(cè)試我們的中間件,我們需要在/etc/hosts中添加想要測(cè)試的子域名。要用別名為djangoCourse對(duì)象測(cè)試中間件,需要在/etc/hosts文件添加這一行:

127.0.0.1 django.educaproject.com 

然后在瀏覽器中打開(kāi)https://django.educaproject.com/。中間件會(huì)通過(guò)子域名找到課程,并重定向到https://educaproject.com/course/django/。

13.5 實(shí)現(xiàn)自定義管理命令

Django允許你的應(yīng)用為manage.py工具注冊(cè)自定義管理命令。例如,我們?cè)诘诰耪率褂?code>makemessages和compilemessages管理命令來(lái)創(chuàng)建和編譯轉(zhuǎn)換文件。

一個(gè)管理命令由一個(gè)Python模塊組成,其中Python模塊包括一個(gè)從django.core.management.BaseCommand繼承的Command類(lèi)。你可以創(chuàng)建簡(jiǎn)單命令,或者讓它們接收位置和可選參數(shù)作為輸入。

Django在INSTALLED_APPS設(shè)置中激活的每個(gè)應(yīng)用的management/commands/目錄中查找管理命令。發(fā)現(xiàn)的每個(gè)模塊注冊(cè)為以其命名的管理命令。

你可以在這里進(jìn)一步學(xué)習(xí)自定義管理命令。

我們將注冊(cè)一個(gè)自定義管理命令,提供學(xué)生至少報(bào)名一個(gè)課程。該命令會(huì)給注冊(cè)時(shí)間長(zhǎng)于指定時(shí)間,但尚未報(bào)名任何課程的用戶發(fā)送一封提醒郵件。

students應(yīng)用目錄中創(chuàng)建以下文件結(jié)構(gòu):

management/ __init__.py commands/ __init__.py enroll_reminder.py 

編輯enroll_reminder.py文件,并添加以下代碼:

import datetime from django.conf import settings from django.core.management.base import BaseCommand from django.core.mail import send_mass_mail from django.contrib.auth.models import User from django.db.models import Countclass Command(BaseCommand): help = 'Send an e-mail reminder to users registered more \ than N days that are not enrolled into any courses yet'def add_arguments(self, parser): parser.add_argument('--days', dest='days', typy=int)def handle(self, *args, **kwargs): emails = [] subject = 'Enroll in a course' date_joined = datetime.date.today() - datetime.timedelta(days=options['days']) users = User.objects.annotate( course_count=Count('courses_enrolled') ).filter( course_count=0, date_joined__lte=date_joined ) for user in users: message = 'Dear {},\n\nWe noticed that you didn\'t enroll in any courses yet.'.format(user.first_name) emails.append(( subject, message, settings.DEFAULT_FROM_EMAIL, [user.email] )) send_mass_mail(emails) self.stdout.write('Sent {} reminders' % len(emails)) 

這是我們的enroll_reminder命令。這段代碼完成以下任務(wù):

  • Command類(lèi)從BaseCommand繼承。
  • 我們包括了一個(gè)help屬性。該屬性為命令提供了一個(gè)簡(jiǎn)單描述,如果你執(zhí)行python manage.py help enroll_reminder命令,則會(huì)打印這個(gè)描述。
  • 我們使用add_arguments()方法添加--days命名參數(shù)。該參數(shù)用于指定用戶注冊(cè)了,但沒(méi)有報(bào)名參加任何課程,從而需要接收提醒郵件的最小天數(shù)。
  • handle()方法包括實(shí)際命令。我們從命令行解析中獲得days屬性。我們檢索注冊(cè)天數(shù)超過(guò)指定天數(shù),當(dāng)仍沒(méi)有參加任何課程的用戶。我們用一個(gè)用戶報(bào)名參加的總課程數(shù)量注解(annotate)QuerySet實(shí)現(xiàn)此目的。我們?yōu)槊總€(gè)用戶生成一封提醒郵件,并把它添加到emails列表中。最后,我們用send_mass_mail()函數(shù)發(fā)送郵件,這個(gè)函數(shù)打開(kāi)單個(gè)SMTP連接發(fā)送所有郵件,而不是每發(fā)送一封郵件打開(kāi)一個(gè)連接。

你已經(jīng)創(chuàng)建了第一個(gè)管理命令。打開(kāi)終端執(zhí)行你的命令:

python manage.py enroll_reminder --days=20 

如果你沒(méi)有正在運(yùn)行的本地SMTP服務(wù)器,你可以參考第二章,我們?yōu)榈谝粋€(gè)Django項(xiàng)目配置了SMTP設(shè)置。另外,你可以添加以下行到settings/local.py文件,讓Django在開(kāi)發(fā)期間輸出郵件到標(biāo)準(zhǔn)輸出:

EMAIL_BACKEND = 'django.core.mail.backends.console.EmailBackend' 

讓我們調(diào)度管理命令,讓服務(wù)器沒(méi)有早上8點(diǎn)運(yùn)行它。如果你正在使用基于Unix的系統(tǒng),比如Linux或者M(jìn)ac OS X,打開(kāi)終端執(zhí)行crontab -e來(lái)編輯計(jì)劃任務(wù)。在其中添加下面這一行:

0 8 * * * python /path/to/educa/manage.py enroll_reminder --days=20 --settings=educa.settings.pro 

如果你不熟悉Cron,你可以在這里學(xué)習(xí)它。

如果你正在使用Windows,你可以使用Task scheduler調(diào)度任務(wù)。你可以在這里進(jìn)一步學(xué)習(xí)它。

定期執(zhí)行操作的另一個(gè)方法是用Celery創(chuàng)建和調(diào)度任務(wù)。記住,我們?cè)诘谄哒率褂肅elery執(zhí)行了異步任務(wù)。除了使用Cron創(chuàng)建和調(diào)用管理命令,你還可以使用Celery beat scheduler創(chuàng)建異步任務(wù)并執(zhí)行它們。你可以在這里進(jìn)一步學(xué)習(xí)使用Celery調(diào)度定時(shí)任務(wù)。

對(duì)要使用Cron或者Windows調(diào)度任務(wù)控制面板調(diào)度的獨(dú)立腳本使用管理命令。

Django還包括一個(gè)用Python調(diào)用管理命令的工具。你可以在代碼中如下執(zhí)行管理命令:

from django.core import management management.call_command('enroll_reminder', days=20) 

恭喜你!現(xiàn)在你已經(jīng)為你的應(yīng)用創(chuàng)建了自定義管理命令,并在需要時(shí)調(diào)度它們。

13.6 總結(jié)

在這一章中,你使用uWSGINginx配置了一個(gè)生產(chǎn)環(huán)境。你還實(shí)現(xiàn)了一個(gè)自定義中間件,并學(xué)習(xí)了如何創(chuàng)建自定義管理命令。


本頁(yè)內(nèi)容由塔燈網(wǎng)絡(luò)科技有限公司通過(guò)網(wǎng)絡(luò)收集編輯所得,所有資料僅供用戶學(xué)習(xí)參考,本站不擁有所有權(quán),如您認(rèn)為本網(wǎng)頁(yè)中由涉嫌抄襲的內(nèi)容,請(qǐng)及時(shí)與我們聯(lián)系,并提供相關(guān)證據(jù),工作人員會(huì)在5工作日內(nèi)聯(lián)系您,一經(jīng)查實(shí),本站立刻刪除侵權(quán)內(nèi)容。本文鏈接:http://caipiao93.cn/20473.html
相關(guān)開(kāi)發(fā)語(yǔ)言
 八年  行業(yè)經(jīng)驗(yàn)

多一份參考,總有益處

聯(lián)系深圳網(wǎng)站公司塔燈網(wǎng)絡(luò),免費(fèi)獲得網(wǎng)站建設(shè)方案及報(bào)價(jià)

咨詢相關(guān)問(wèn)題或預(yù)約面談,可以通過(guò)以下方式與我們聯(lián)系

業(yè)務(wù)熱線:余經(jīng)理:13699882642

Copyright ? 2013-2018 Tadeng NetWork Technology Co., LTD. All Rights Reserved.    

  • QQ咨詢
  • 在線咨詢
  • 官方微信
  • 聯(lián)系電話
    座機(jī)0755-29185426
    手機(jī)13699882642
  • 預(yù)約上門(mén)
  • 返回頂部