Django工程目錄結(jié)構(gòu)優(yōu)化

原文的鏈接:http://www.loonapp.com/blog/11/ 

偶然看到一份關(guān)于Django工程目錄的文章,英文版版的,覺得寫得不錯(cuò)。在此翻譯下供讀者參考

Django 工程目錄結(jié)構(gòu)

你已經(jīng)配置好你的Heroku賬戶(譯者注:Heroku是一個(gè)老牌的免費(fèi)云空間),并且創(chuàng)建了第一個(gè)Heroku應(yīng)用,讓我們來討論一個(gè)非常重要的話題(雖然經(jīng)常被忽略):Django工程結(jié)構(gòu)管理。

概述

多數(shù)Django工程非?;靵y。不幸的是默認(rèn)的Django工程布局并沒有對此有任何幫助,它過于簡單對工程的管理導(dǎo)致在處理大的工程時(shí)帶來很多維護(hù)性問題。

本文將幫助讓你的工程有個(gè)合理的布局。致力于:

  • 遵循最佳實(shí)踐

  • 讓你的工程盡可能地直觀--你(作為開發(fā)者)可以立即認(rèn)出代碼每個(gè)部分的作用

  • 讓你工程仍然保持規(guī)范隨著你的工程中的應(yīng)用越來越多。

  • 讓你工程在不同環(huán)境下部署更加方便

  • 讓其他程序員喜歡你的代碼

具體步驟

這部分我將和你一起開始一個(gè)新的項(xiàng)目。過程中,你需要將你的項(xiàng)目目錄結(jié)構(gòu)調(diào)整為下面描述的布局。

本文描述了高維護(hù)性結(jié)構(gòu)分明的Django項(xiàng)目布局的最佳實(shí)踐。

基礎(chǔ)- 缺省的Django項(xiàng)目

在深入之前,讓我們創(chuàng)建一個(gè)新的Django項(xiàng)目(工程)

$django-admin.py startproject djanolicious
$cd djangolicious
$tree .
.
├── djangolicious
│   ├── __init__.py
│   ├── settings.py
│   ├── urls.py
│   └── wsgi.py
└── manage.py

1個(gè)目錄,5個(gè)文件

在根目錄djangolicious下,可以得到:

項(xiàng)目目錄:djangolicious

manage.py腳本:用于管理Django站點(diǎn)

在項(xiàng)目目錄djangolicious里包含:

settings.py: 包含項(xiàng)目的所有配置參數(shù)

urls.py: URL根配置

wsgi.py: 內(nèi)置runserver命令的WSGI應(yīng)用配置

init.py: 用來告訴python,當(dāng)前目錄是python模塊

現(xiàn)在讓我們來看下一個(gè)工程的基本架構(gòu),讓我們來做些改進(jìn)。

管理項(xiàng)目需求說明

首先我們在項(xiàng)目中新建一個(gè)文件:requirements.txt。每個(gè)Django項(xiàng)目都應(yīng)該有一個(gè)頂級的requirements.txt文件來列出項(xiàng)目中所有使用到的python包。

Note:如果你對于requirements文件不太熟悉,你可以閱讀Heroku指引 來通過pip管理python的需求關(guān)系。

requirement.txt中類似如下內(nèi)容:

Django==1.6
psycopy2==2.4.5
South==0.7.3
gunicorn==0.14.1
nrerelic==1.2.0.246
django-cerlery==2.4.2

創(chuàng)建requirements文件是為了讓其他開發(fā)者 拷貝你的項(xiàng)目代碼后可以快速地根據(jù)此文件中內(nèi)容安裝好必須的python依賴包。這樣他們可以方便地運(yùn)行你的代碼,而不必煞費(fèi)苦心地猜測項(xiàng)目依賴包的版本。

現(xiàn)在你知道為什么我們需要這么做了,照做吧!

第一步--模塊化

在項(xiàng)目目錄中創(chuàng)建一個(gè)頂級的requirement.txt是必須遵循的要求,而且這樣可以保證可以方便地管理項(xiàng)目依賴關(guān)系

這意味著:很有可能,項(xiàng)目的開發(fā)環(huán)境依賴關(guān)系不同于你的生產(chǎn)環(huán)境,所有你需要將你的開發(fā)和生產(chǎn)環(huán)境的依賴都放到requirement.txt中,但是這會使得管理起來比較困難。

所以,最好是區(qū)分好不同環(huán)境的依賴和需求

我們的做法如下(在項(xiàng)目djangolicious根目錄下):

$ls
djangolicious manage.py
$touch requirements.txt
$mkdir requirements
$touch requirements/{common.txt,dev.txt,prod.txt,test.txt}
$tree.
.
|-- djangolicious
|   |-- __init__.py
|   |-- settings.py
|   |-- urls.py
|   |-- wsgi.py 
|-- manage.py
|-- requirements
|   |-- common.txt
|   |-- dev.txt
|   |-- prod.txt
|   |-- test.txt
|-- requirements.txt

2個(gè)目錄,10個(gè)文件

可以看出,我新建了一個(gè)頂級目錄:requirements,包含一系列的需求說明文件,分別針對每個(gè)環(huán)境。

如果你的應(yīng)用只需要在開發(fā)環(huán)境下運(yùn)行,那么只需要在一個(gè)dev.txt文件。如果你的應(yīng)用需要開發(fā)、生產(chǎn)、測試、tom和rudy環(huán)境下運(yùn)行--那么就分別為他們創(chuàng)建一個(gè).txt文件

Note:common.txt內(nèi)含各種環(huán)境下共享的需求說明。例如Django。所有環(huán)境下都需要Django,不管是開發(fā)環(huán)境還是生產(chǎn)環(huán)境,你都需要使用它。

將各類需求文件分開的目的是,當(dāng)作為程序員的我只需要在本地環(huán)境下運(yùn)行項(xiàng)目,那么我只需要安裝requirement/dev.txt中提到的軟件包,而不需要安裝其他的包(生產(chǎn)環(huán)境,staging,測試環(huán)境等等)

但是為什么我這么關(guān)心哪些包是我必須安裝的?為什么我不將他們?nèi)堪惭b?

安裝依賴包需要耗費(fèi)很長時(shí)間,對于大型項(xiàng)目來說可能會耗費(fèi)大塊的時(shí)間(30分鐘以上)。

很多需求依賴于外部軟件或者庫文件按裝到你的本地機(jī)器來完成編譯。這么避免安裝庫文件可以節(jié)省時(shí)間還可以免去大量不必要的麻煩,比如要安裝哪個(gè)版本的libxml2和libpq-dev。

降低了初學(xué)者學(xué)習(xí)的門檻。如果的你項(xiàng)目組來了一個(gè)新的開發(fā),嘗試提交代碼,對他來說安裝很少的軟件包就可以運(yùn)行系統(tǒng)要比安裝所有軟件包要簡單的多。

第二步--定義需求文件

現(xiàn)在我們明白了為什么要模塊化需求說明文件,下面了解下實(shí)踐中需求說明文件的具體內(nèi)容。

下面我列出了4個(gè)從我實(shí)際項(xiàng)目中拿來的需求說明文件,我將詳細(xì)的給予說明。

首先,requirements/common.txt文件列出了所有基本的需求包,其中的么個(gè)軟件包在任何環(huán)境都是必須的(不管是開發(fā)環(huán)境,測試環(huán)境還是生產(chǎn)環(huán)境等的):

# requirements/common.txt
Django==1.4
django-cache-machine==0.6
django-celery==2.5.5
django-dajaxice==0.2
django-guardian==1.0.4
django-kombu==0.9.4
django-pagination==1.0.7
django-sorting==0.1
django-tastypie==0.9.11
Fabric==1.4.1
lxml==2.3.4
pyst2==0.4
South==0.7.4
Sphinx==1.1.3

下面的requirements/dev.txt文件包含了我的開發(fā)環(huán)境所需要包,其中的包只有是在開發(fā)環(huán)境下才會用到。

# requirements/dev.txt
-r common.txt
django-debug-toolbar==0.9.4

在我的開發(fā)環(huán)境,我通常使用輕量級的SQLite3數(shù)據(jù)庫(所以我不需要安裝任何驅(qū)動(dòng)程序),而且非常好用的包django-debug-toolbar可以允許我檢查數(shù)據(jù)庫查詢和性能問題,等等。

可能你會疑惑文件第一行的作用,'-r common.txt'告訴pip引入所有通用的依賴包附加到后面列舉內(nèi)容。

這將允許我在命令行中直接運(yùn)行pip intal -r requirements/dev.txt來安裝開發(fā)環(huán)境需要的所有依賴包:

$ pip install -r requirements/dev.txt
Downloading/unpacking Django==1.4 (from -r requirements/common.txt (line 1))
  Downloading Django-1.4.tar.gz (7.6Mb): 7.6Mb downloaded
  Running setup.py egg_info for package Django
 
Downloading/unpacking django-cache-machine==0.6 (from -r requirements/common.txt (line 2))
  Downloading django-cache-machine-0.6.tar.gz
  Running setup.py egg_info for package django-cache-machine
 
... snipped for brevity ...

從上面的運(yùn)行結(jié)果可以看出,非常好用!當(dāng)我們使用pip安裝requirements/dev.txt中包,它不僅成功安裝了開發(fā)環(huán)境中需要的依賴包,同時(shí)也將common.txt中列舉的包都安裝好了!非常漂亮!

下面是一個(gè)簡單的requirements/pord.txt需求說明文件。其中包含了所有生產(chǎn)環(huán)境的依賴包和基本的依賴包:

# requirements/prod.txt
-r common.txt
boto==2.1.1
cssmin==0.1.4
django-compressor==1.1.2
django-htmlmin==0.5.1
django-pylibmc-sasl==0.2.4
django-storages==1.1.3
gunicorn==0.14.1
newrelic==1.2.0.246
psycopg2==2.4.5
pylibmc==1.2.2
raven==1.3.5
slimit==0.6

最后,這是一個(gè)比較舊的requirements/test.txt文件,列出測試環(huán)境下的依賴包。這些包用于項(xiàng)目的單元測試環(huán)節(jié)。

# requirements/test.txt
-r common.txt
django-coverage==1.2.2
django-nose==0.1.3
mock==0.8.0
nosexcover==1.0.7   

當(dāng)我需要在本地開發(fā)環(huán)境下運(yùn)行我的代碼,我就安裝requirements/dev.txt中的依賴包

當(dāng)我在生產(chǎn)環(huán)境下運(yùn)行我的代碼,就安裝requirements/prod.txt中的依賴包

當(dāng)我要針對我的代碼做一些測試的時(shí)候,我就安裝requirements/test.txt中的依賴包

重點(diǎn)在于將你的項(xiàng)目依賴文件按照以下原則來拆分:

  • 簡單的

  • 高效的

  • 直觀的

第三步--Heroku最佳實(shí)踐

現(xiàn)在,我們模塊化了我們的需求說明文件。我敢說你一定疑惑:為什么在項(xiàng)目根目錄下還有個(gè)requirement.txt的文件?

原因如下:

標(biāo)準(zhǔn)化要求存在requirements.txt文件

Heroku在你部署項(xiàng)目的時(shí)候會自動(dòng)讀取你根目錄下下的requirements.txt文件,并且將這些需求包安裝起來。

Heroku會安裝你在requirements.txt中定義的所有包,你可以有多種選擇:

讓Heroku安裝所有的依賴包:comon.txt,dev.txt,prod.txt等

讓Heroku只安裝他需要的包

我們使用Heroku來部署我們的站點(diǎn),所有最好是讓Heroku只安裝必須的包。

因?yàn)镠eroku需要做的事情少了,這會讓我們部署后的項(xiàng)目更加快速。

打開根目錄下的requirements.txt文件然后輸入以下內(nèi)容:
#Install all of our production dependencies only.
-r requirements/prod.txt
這樣Heroku就會安裝我們的要求來安裝需要的包。

分離應(yīng)用和庫文件

管理Django工程接下來的工作就是把你的應(yīng)用從庫中分離出來。

總所周知,每個(gè)Django工程包括一系列的應(yīng)用。有些應(yīng)用中包含模型和視圖等等。還有些是輔助性的應(yīng)用。

通常,這些輔助應(yīng)用用于自定義templatetag,管理命令以及一些其他代碼。請不要將這些放到別的應(yīng)用里面。

幸運(yùn)的沒,有一種簡單的方法來構(gòu)建的Django項(xiàng)目:

開發(fā)人員可以很容易地找到你的django應(yīng)用

開發(fā)人員可以很容易的找到你的django庫文件

不要在你工程目錄下包含大量的自定義應(yīng)用,不要讓你的目錄結(jié)果混亂,而很難找到你想要的東西

我都會在每個(gè)Django工程的主目錄下創(chuàng)建兩個(gè)目錄:apps和libs用來各自存放應(yīng)用和庫文件。

再看我們的例子工程:djangolicious,我的做法如下:

$ mkdir djangolicious/apps
$ mkdir djangolicious/libs
$ touch djangolicious/apps/__init__.py
$ touch djangolicious/libs/__init__.py
$ tree .
.
├── djangolicious
│   ├── apps
│   │   └── __init__.py
│   ├── __init__.py
│   ├── libs
│   │   └── __init__.py
│   ├── settings.py
│   ├── urls.py
│   └── wsgi.py
├── manage.py
├── requirements
│   ├── common.txt
│   ├── dev.txt
│   ├── prod.txt
│   └── test.txt
└── requirements.txt

4個(gè)目錄,12個(gè)文件

如上所示,我的djangolicious工程中包含了新的apps目錄和libs目錄。剩下的就是將Django應(yīng)用和庫移動(dòng)到合適的位置。

在djangolicious的例子中,我創(chuàng)建了一些django應(yīng)用和庫,現(xiàn)在到時(shí)候?qū)jango應(yīng)用移動(dòng)到合適位置。

$ cd djangolicious/apps
$ django-admin.py startapp blog
$ django-admin.py startapp reader
$ django-admin.py startapp news
$ cd ../libs
$ django-admin.py startapp management
$ django-admin.py startapp display
$ cd ../..
$ tree .
.
├── djangolicious
│   ├── apps
│   │   ├── blog
│   │   │   ├── __init__.py
│   │   │   ├── models.py
│   │   │   ├── tests.py
│   │   │   └── views.py
│   │   ├── __init__.py
│   │   ├── news
│   │   │   ├── __init__.py
│   │   │   ├── models.py
│   │   │   ├── tests.py
│   │   │   └── views.py
│   │   └── reader
│   │       ├── __init__.py
│   │       ├── models.py
│   │       ├── tests.py
│   │       └── views.py
│   ├── __init__.py
│   ├── libs
│   │   ├── display
│   │   │   ├── __init__.py
│   │   │   ├── models.py
│   │   │   ├── tests.py
│   │   │   └── views.py
│   │   ├── __init__.py
│   │   └── management
│   │       ├── __init__.py
│   │       ├── models.py
│   │       ├── tests.py
│   │       └── views.py
│   ├── settings.py
│   ├── urls.py
│   └── wsgi.py
├── manage.py
├── requirements
│   ├── common.txt
│   ├── dev.txt
│   ├── prod.txt
│   └── test.txt
└── requirements.txt

9個(gè)目錄,32個(gè)文件

現(xiàn)在我們的工程已經(jīng)有了實(shí)際的架構(gòu)!已經(jīng)將django應(yīng)用和庫文件清晰地分開了。這樣不僅很容易找到想要的應(yīng)用或者庫,而且目錄結(jié)構(gòu)也是非常的清晰。

移動(dòng)應(yīng)用和庫文件后,還需要更新你的引入路徑。如果你之前的是這么寫的:

# blog/views.py
from djangolicious.news.models import Newspaper
from djangolicious.display.templatetags import top_stories

那么你需要改成:

# blog/views.py
from djangolicious.apps.news.models import Newspaper
from djangolicious.libs.display.templatetags import top_stories

盡管import語句變長了,我發(fā)現(xiàn)這對于我這個(gè)開發(fā)者來找到我所引入的需要修改的app、librarie是很有幫助的。

你還需要更新你的settings文件來包含新的應(yīng)用的路徑:

# settings.py
INSTALLED_APPS = (
    ...
    'djangolicious.apps.blog',
    'djangolicious.apps.news',
    'djangolicious.apps.reader',
    ...
)

構(gòu)建一個(gè)完美的Django settings模塊

構(gòu)建完美的Django settings模塊被認(rèn)為是Django開發(fā)的“必殺技”。每個(gè)開發(fā)者都有著自己的想法,也可能會為此爭論。

然而,很多人的做法真實(shí)非常錯(cuò)誤的。

在此,我來展示了一種正確的方法來構(gòu)建完美的Django settings模塊,不管你工程的大小,需求以及其他因素。

我們所創(chuàng)建的settings模塊:

允許你方便地分離Django各種環(huán)境(開發(fā),生產(chǎn),測試等等)。

允許你保持所有配置信息都在版本控制下。

允許你通過環(huán)境變量將密碼和其他證書從基本代碼中分離出來。

讓你可以方便地修改配置。

第一步--模塊化,模塊化,模塊化

就像我們在前面的章節(jié)中處理需求說明文件那樣,配置信息也需要模塊化!

首先,讓我們處理掉討厭的默認(rèn)settings.py,取而代之的是創(chuàng)建一個(gè)更好的目錄結(jié)構(gòu):

$ rm djangolicious/settings.py
$ mkdir djangolicious/settings
$ touch djangolicious/settings/{__init__.py,common.py,dev.py,prod.py,test.py}
$ tree .
.
├── djangolicious
│   ├── apps
│   │   ├── blog
│   │   │   ├── __init__.py
│   │   │   ├── models.py
│   │   │   ├── tests.py
│   │   │   └── views.py
│   │   ├── __init__.py
│   │   ├── news
│   │   │   ├── __init__.py
│   │   │   ├── models.py
│   │   │   ├── tests.py
│   │   │   └── views.py
│   │   └── reader
│   │       ├── __init__.py
│   │       ├── models.py
│   │       ├── tests.py
│   │       └── views.py
│   ├── __init__.py
│   ├── libs
│   │   ├── display
│   │   │   ├── __init__.py
│   │   │   ├── models.py
│   │   │   ├── tests.py
│   │   │   └── views.py
│   │   ├── __init__.py
│   │   └── management
│   │       ├── __init__.py
│   │       ├── models.py
│   │       ├── tests.py
│   │       └── views.py
│   ├── settings
│   │   ├── common.py
│   │   ├── dev.py
│   │   ├── __init__.py
│   │   ├── prod.py
│   │   └── test.py
│   ├── urls.py
│   └── wsgi.py
├── manage.py
├── requirements
│   ├── common.txt
│   ├── dev.txt
│   ├── prod.txt
│   └── test.txt
└── requirements.txt

和需求說明文件一樣,settings模塊也應(yīng)該針對每個(gè)環(huán)境一個(gè)配置文件(dev.py,prod.py,test.py),和一個(gè)被各種環(huán)境共享的文件(common.py)。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容