本高級(jí)教程上接教程 6。我們將把我們的網(wǎng)頁投票轉(zhuǎn)換成一個(gè)獨(dú)立的Python包,這樣你可以在-其它項(xiàng)目中重用或者分享給其它人。
如果你最近沒有完成教程1–6,我們建議你閱讀它們使得你的示例項(xiàng)目與下面描述的相匹配。
設(shè)計(jì)、構(gòu)建、測(cè)試和維護(hù)一個(gè)網(wǎng)頁應(yīng)用有許多工作要做。許多Python 和 Django 項(xiàng)目都有常見的共同問題。如果我們可以節(jié)省一些這些重復(fù)的工作會(huì)不會(huì)很棒?
可重用性是Python 中一種生活的態(tài)度。Python包索引 (PyPI) 具有廣泛的包,你可以在你自己的Python程序中使用。調(diào)查一下Django Packages中已經(jīng)存在的可重用的應(yīng)用,你可以結(jié)合它們到你的項(xiàng)目。Django 自身也只是一個(gè)Python 包。這意味著你可以獲取已經(jīng)存在的Python包和Django應(yīng)用并將它們?nèi)诤系侥阕约旱木W(wǎng)頁項(xiàng)目。你只需要編寫你項(xiàng)目的獨(dú)特的部分。
比如說,你正在開始一個(gè)新的項(xiàng)目,需要一個(gè)像我們正在編寫的投票應(yīng)用。你如何讓該應(yīng)用可重用?幸運(yùn)的是,你已經(jīng)在正確的道路上。在教程 3中,我們看到我們可以如何使用include將投票應(yīng)用從項(xiàng)目級(jí)別的URLconf 解耦。在本教程中,我們將更進(jìn)一步,讓你的應(yīng)用在新的項(xiàng)目中容易地使用并隨時(shí)可以發(fā)布給其它人安裝和使用。
包?應(yīng)用?
Python 包 提供的方式是分組相關(guān)的Python 代碼以容易地重用。一個(gè)包包含一個(gè)或多個(gè)Python代碼(也叫做“模塊”)。
包可以通過import foo.bar 或from foo import bar 導(dǎo)入。如果一個(gè)目錄(例如polls)想要形成一個(gè)包,它必須包含一個(gè)特殊的文件init.py,即使這個(gè)文件為空。
一個(gè)Django 應(yīng)用 只是一個(gè)Python包,它特意用于Django項(xiàng)目中。一個(gè)應(yīng)用可以使用常見的Django 約定,例如具有models、tests、urls和views 子模塊。
后面我們使用打包這個(gè)詞來描述將一個(gè)Python包變得讓其他人易于安裝的過程。我們知道,這可能有點(diǎn)繞人。
經(jīng)過前面的教程之后,我們的項(xiàng)目應(yīng)該看上去像這樣:
mysite/
manage.py
mysite/
__init__.py
settings.py
urls.py
wsgi.py
polls/
__init__.py
admin.py
migrations/
__init__.py
0001_initial.py
models.py
static/
polls/
images/
background.gif
style.css
templates/
polls/
detail.html
index.html
results.html
tests.py
urls.py
views.py
templates/
admin/
base_site.html
你在教程 2中創(chuàng)建了mysite/templates ,在教程 3中創(chuàng)建了polls/templates。 現(xiàn)在你可能更加清晰為什么我們?yōu)轫?xiàng)目和應(yīng)用選擇單獨(dú)的模板目錄:屬于投票應(yīng)用的部分全部在polls中。它使得該應(yīng)用自包含且更加容易丟到一個(gè)新的項(xiàng)目中。
現(xiàn)在可以拷貝polls目錄到一個(gè)新的Django項(xiàng)目并立即使用。然后它還不能充分準(zhǔn)備好到可以立即發(fā)布。由于這點(diǎn),我們需要打包這個(gè)應(yīng)用來讓它對(duì)其他人易于安裝。
Python 打包的目前狀態(tài)因?yàn)橛卸喾N工具而混亂不堪。對(duì)于本教程,我們打算使用setuptools來構(gòu)建我們的包。它是推薦的打包工具(已經(jīng)與distribute 分支合并)。我們還將使用pip來安裝和卸載它。現(xiàn)在你應(yīng)該安裝這兩個(gè)包。如果你需要幫助,你可以參考如何使用pip安裝Django。你可以使用同樣的方法安裝setuptools。
Python packaging refers to preparing your app in a specific format that can be easily installed and used. Django 自己是以非常相似的方式打包起來的。對(duì)于一個(gè)像polls這樣的小應(yīng)用,這個(gè)過程不是太難。
首先,在你的Django項(xiàng)目之外,為polls創(chuàng)建一個(gè)父目錄。稱這個(gè)目錄為django-polls。
為你的應(yīng)用選擇一個(gè)名字
讓為你的包選擇一個(gè)名字時(shí),檢查一下PyPI中的資源以避免與已經(jīng)存在的包有名字沖突。當(dāng)創(chuàng)建一個(gè)要發(fā)布的包時(shí),在你的模塊名字前面加上django-通常很有用。 這有助于其他正在查找Django應(yīng)用的人區(qū)分你的應(yīng)用是專門用于Django的。
應(yīng)用的標(biāo)簽(應(yīng)用的包的點(diǎn)分路徑的最后部分)在INSTALLED_APPS中必須唯一。避免使用與Django的contrib 包 中任何一個(gè)使用相同的標(biāo)簽,例如auth、admin和messages。
將polls 目錄移動(dòng)到django-polls目錄。
創(chuàng)建一個(gè)包含一些內(nèi)容的文件django-polls/README.rst:
django-polls/README.rst
=====
Polls
=====
Polls is a simple Django app to conduct Web-based polls. For each
question, visitors can choose between a fixed number of answers.
Detailed documentation is in the "docs" directory.
Quick start
-----------
1. Add "polls" to your INSTALLED_APPS setting like this::
INSTALLED_APPS = (
...
'polls',
)
2. Include the polls URLconf in your project urls.py like this::
url(r'^polls/', include('polls.urls')),
3. Run `python manage.py migrate` to create the polls models.
4. Start the development server and visit http://127.0.0.1:8000/admin/
to create a poll (you'll need the Admin app enabled).
5. Visit http://127.0.0.1:8000/polls/ to participate in the poll.
創(chuàng)建一個(gè)django-polls/LICENSE文件。選擇License超出本教程的范圍,但值得一說的是公開發(fā)布的代碼如果沒有License是毫無用處的。Django和許多與Django兼容的應(yīng)用以BSD License 發(fā)布;然而,你可以隨便挑選自己的License。只需要知道你的License的選則將影響誰能夠使用你的代碼。
下一步我們將創(chuàng)建一個(gè)setup.py 文件,它提供如何構(gòu)建和安裝該應(yīng)用的詳細(xì)信息。該文件完整的解釋超出本教程的范圍,setuptools 文檔 有很好的解釋。創(chuàng)建一個(gè)文件django-polls/setup.py,其內(nèi)容如下:
django-polls/setup.py
import os
from setuptools import setup
with open(os.path.join(os.path.dirname(__file__), 'README.rst')) as readme:
README = readme.read()
# allow setup.py to be run from any path
os.chdir(os.path.normpath(os.path.join(os.path.abspath(__file__), os.pardir)))
setup(
name='django-polls',
version='0.1',
packages=['polls'],
include_package_data=True,
license='BSD License', # example license
description='A simple Django app to conduct Web-based polls.',
long_description=README,
url='http://www.example.com/',
author='Your Name',
author_email='yourname@example.com',
classifiers=[
'Environment :: Web Environment',
'Framework :: Django',
'Intended Audience :: Developers',
'License :: OSI Approved :: BSD License', # example license
'Operating System :: OS Independent',
'Programming Language :: Python',
# Replace these appropriately if you are stuck on Python 2.
'Programming Language :: Python :: 3',
'Programming Language :: Python :: 3.2',
'Programming Language :: Python :: 3.3',
'Topic :: Internet :: WWW/HTTP',
'Topic :: Internet :: WWW/HTTP :: Dynamic Content',
],
)
默認(rèn)只有Python模塊和包會(huì)包含進(jìn)包中。如果需要包含額外的文件,我們需要?jiǎng)?chuàng)建一個(gè)MANIFEST.in文件。上一步提到的setuptools 文檔對(duì)這個(gè)文件有更詳細(xì)的討論。如果要包含模板、README.rst和我們的LICENSE 文件,創(chuàng)建一個(gè)文件django-polls/MANIFEST.in,其內(nèi)容如下:
django-polls/MANIFEST.in
include LICENSE
include README.rst
recursive-include polls/static *
recursive-include polls/templates *
將詳細(xì)的文檔包含進(jìn)你的應(yīng)用中,它是可選的,但建議你這樣做。創(chuàng)建一個(gè)空的目錄django-polls/docs用于將來存放文檔。向django-polls/MANIFEST.in添加另外一行:
recursive-include docs *
注意docs不會(huì)包含進(jìn)你的包中除非你添加一些文件到它下面。許多Django應(yīng)用還通過類似readthedocs.org這樣的站點(diǎn)提供它們的在線文檔.
試著通過python setup.py sdist 構(gòu)建你的包(從django-polls的內(nèi)部運(yùn)行)。這創(chuàng)建一個(gè)dist目錄并構(gòu)建一個(gè)新包django-polls-0.1.tar.gz。
更多關(guān)于打包的信息,參見Python 的 打包和分發(fā)項(xiàng)目的教程。
因?yàn)?,我們將polls 目錄移到項(xiàng)目的目錄之外,它不再工作了。我們將通過安裝我們的新的django-polls包來修復(fù)它。
安裝成某個(gè)用戶的庫
以下的步驟將安裝django-polls 成某個(gè)用戶的庫。根據(jù)用戶安裝相比系統(tǒng)范圍的安裝具有許多優(yōu)點(diǎn),例如用于沒有管理員權(quán)限的系統(tǒng)上以及防止你的包影響系統(tǒng)的服務(wù)和機(jī)器上的其它用戶。
注意根據(jù)用戶的安裝仍然可以影響以該用戶身份運(yùn)行的系統(tǒng)工具,所以virtualenv 是更健壯的解決辦法(見下文)。
安裝這個(gè)包,使用pip(你已經(jīng)安裝好它了,對(duì)吧?):
pip install --user django-polls/dist/django-polls-0.1.tar.gz
如果幸運(yùn),你的Django 項(xiàng)目現(xiàn)在應(yīng)該可以再次正確工作。請(qǐng)重新運(yùn)行服務(wù)器以證實(shí)這點(diǎn)。
若要卸載這個(gè)包,使用pip:
pip uninstall django-polls
既然我們已經(jīng)打包并測(cè)試過django-polls,是時(shí)候與世界共享它了!要不是它僅僅是個(gè)例子,你現(xiàn)在可以:
前面,我們將poll 安裝成一個(gè)用戶的庫。它有一些缺點(diǎn):
特別是一旦你維護(hù)幾個(gè)Django項(xiàng)目,這些情況就會(huì)出現(xiàn)。如果確實(shí)出現(xiàn),最好的解決辦法是使用virtualenv。這個(gè)工具允許你維護(hù)多個(gè)分離的Python環(huán)境,每個(gè)都具有它自己的庫和包的命名空間。
譯者:Django 文檔協(xié)作翻譯小組,原文:How to write reusable apps。
本文以 CC BY-NC-SA 3.0 協(xié)議發(fā)布,轉(zhuǎn)載請(qǐng)保留作者署名和文章出處。
Django 文檔協(xié)作翻譯小組人手緊缺,有興趣的朋友可以加入我們,完全公益性質(zhì)。交流群:467338606。