鍍金池/ 教程/ Python/ 高級(jí)教程:如何編寫可重用的應(yīng)用
點(diǎn)擊劫持保護(hù)
安全問題歸檔
Model 類參考
將遺留數(shù)據(jù)庫整合到Django
關(guān)聯(lián)對(duì)象參考
內(nèi)建基于類的視圖的API
聚合
Django 中的用戶認(rèn)證
django.contrib.humanize
Django管理文檔生成器
分頁
使用Django輸出CSV
加密簽名
文件儲(chǔ)存API
安全
Django中的測(cè)試
國(guó)際化和本地化
為Django編寫首個(gè)補(bǔ)丁
條件表達(dá)式
日志
模型元選項(xiàng)
部署靜態(tài)文件
執(zhí)行查詢
使用Django認(rèn)證系統(tǒng)
基于類的視圖
中間件
編寫自定義的django-admin命令
Django 的設(shè)置
格式本地化
數(shù)據(jù)庫訪問優(yōu)化
錯(cuò)誤報(bào)告
基于類的內(nèi)建通用視圖
編寫自定義存儲(chǔ)系統(tǒng)
編寫你的第一個(gè) Django 程序 第3部分
編寫數(shù)據(jù)庫遷移
使用表單
編寫你的第一個(gè) Django 程序 第2部分
編寫你的第一個(gè) Django 程序 第1部分
如何使用會(huì)話
系統(tǒng)檢查框架
新手入門
信號(hào)
編寫視圖
如何使用WSGI 部署
編寫你的第一個(gè)Django應(yīng)用,第6部分
常見的網(wǎng)站應(yīng)用工具
Widgets
內(nèi)建的視圖
模型實(shí)例參考
視圖層
Django中的密碼管理
高級(jí)教程:如何編寫可重用的應(yīng)用
國(guó)際化和本地化
"本地特色"附加功能
TemplateResponse 和 SimpleTemplateResponse
模式編輯器
文件上傳
快速安裝指南
部署 Django
表單 API
表單素材 ( <code>Media</code> 類)
管理文件
其它核心功能
查找 API 參考
表單
Admin
數(shù)據(jù)庫函數(shù)
自定義查找
使用基于類的視圖處理表單
管理操作
開發(fā)過程
編寫你的第一個(gè)Django應(yīng)用,第5部分
進(jìn)行原始的sql查詢
模型層
多數(shù)據(jù)庫
編寫你的第一個(gè) Django 程序 第4部分
Django安全
Django 初探
Django異常
重定向應(yīng)用
按需內(nèi)容處理
管理器
視圖裝飾器
驗(yàn)證器
使用Django輸出PDF
File對(duì)象
Django 的快捷函數(shù)
基于類的通用視圖 —— 索引
為模型提供初始數(shù)據(jù)
模板層
URL調(diào)度器
中間件
模型

高級(jí)教程:如何編寫可重用的應(yīng)用

本高級(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)繞人。

你的項(xiàng)目和你的可重用的應(yīng)用

經(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。

打包你的應(yīng)用

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

發(fā)布你的應(yīng)用:

既然我們已經(jīng)打包并測(cè)試過django-polls,是時(shí)候與世界共享它了!要不是它僅僅是個(gè)例子,你現(xiàn)在可以:

  • 將這個(gè)包用郵件發(fā)送給朋友。
  • 上傳這個(gè)包到你的網(wǎng)站上。
  • 上傳這個(gè)包到一個(gè)公開的倉庫,例如Python 包索引 (PyPI)。packaging.python.org has a good tutorial for doing this.

使用 virtualenv 安裝Python 包

前面,我們將poll 安裝成一個(gè)用戶的庫。它有一些缺點(diǎn):

  • 修改這個(gè)用戶的庫可能影響你的系統(tǒng)上的其它Python 軟件。
  • 你將不可以運(yùn)行這個(gè)包的多個(gè)版本(或者具有相同名字的其它包)。

特別是一旦你維護(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。