全面剖析Python的Django框架中的项目部署技巧第1/2页

项目开始时是一个关键时刻,选择会对项目产生长期的影响。有很多关于如何开始使用Django框架的教程,但很少讨论如何专业地使用Django,或如何使用行业公认的最佳做法来确保你的项目规模的持续增长。事前的筹划让你(和所有同事的生活)在走向将来时更容易。

文章结束时,你将有

  • 一个全功能的Django 1.6项目
  • 源代码受控的所有资源(使用Git或Mercurial)
  • 自动回归和单元测试(使用unittest库)
  • 一个独立于特定环境的安装项目(使用virtualenv)
  • 自动化的部署和测试(使用Fabric)
  • 自动数据库迁移 (使用South)
  • 一个标度你站点的开发工作流程

除第一部在官方教程中外其他部分教程里都没有。它们应该这样。如果你想开始一个新的、生产就绪的Django 1.6项目,请继续往下看。

先决条件

假定你已了解Python的基本知识,同时,以往的一些Django经验会有帮助,但这不是必要的。你需要git或Mercurial来进行版本控制。就这些!
准备安装

我假设你已经安装了Python。如果你没有的话到python.org找到与你系统架构相符的版本下载安装。我使用一个Linode上的64位的Ubuntu服务器,我很高兴使用Linode的服务。

那么,第一步是什么呢?安装Django?不完全是。将安装包直接安装到你当前的site-packages里有一个常见的问题:如果你的机器上有一个以上的Python项目使用Django等其他库,你可能会碰到应用和安装软件库之间依赖性的问题。因此,我们将使用virtualenv和它的延展virtualenvwrapper来管理我们的Django安装。这是Python和Django用户的实践建议。

如果你使用pip来安装第三方库(我不明白你为什么不),你可以通过简单的操作安装virtualenv和virtualenvwrapper。

$ pip install virtualenvwrapper

安装完后,将下附内容添加到你的shell启动配置文件中(.zshrc、.bashrc、.profile等)

代码如下:

export WORKON_HOME=$HOME/.virtualenvsexport PROJECT_HOME=$HOME/directory-you-do-development-insource /usr/local/bin/virtualenvwrapper.sh

重载一下你的启动配置文件(source .zshrc),现在你已经就绪了。

创建一个新环境

创建一个虚拟环境很简单,只需输入

$ mkvirtualenv django_project

“django_project”是你的项目的命名。

你会注意到立马发生的一些事情:

你的shell前面加上了“(django_project)”

distribute和pip被自动安装了

这里是virtualenvwrapper的一个很有用的部分:它会自动为你准备好环境,让你马上可以使用pip安装库。“(django_project)”的部分是提醒你正在使用的是virtualenv而不是你系统上的Python。要退出虚拟环境只需简单输入deactivate即可。当你要回到你的项目开始工作时,只需使用workon django_project即可。需要注意的是这与vanilla virtualenv工具不同,在哪里运行这些命令都可以。

安装Django

“等一下,‘安装Django'?我已经安装Django了!”,太好了。不过你不会用它的。相反,我们将使用机器上的一个被virtualenv管理的且不会被其他用户(或你自己)弄乱的Django安装。在virtualenv中安装Django,只需输入:

$ pip install django

这样最新版的Django将被安装在你的virtualenv环境里,你可以这样确认:

$ which django-admin.py

这会指出你的$HOME/.virtualenvs/目录。如果没有的话,确认你的输入提示里有“(django_project)”。如果没有,使用workon django_project激活virtualenv。

建立项目

在我们真正开始这个项目之前,我们先来谈一谈。我在过去的几年里咨询过很多Django/Python项目并且和许多开发者讨论过。一个具有压倒性的事实是,那些具有最多困难的事情往往都没有使用任何的版本控制。这听起来让人难以置信(想想GitHub的流行程度吧),但是开发者们根本不会去接触版本控制。也有一些人认为"这是个小项目",没有必要使用版本控制。这是错误的。

这里列出的工具不会让你为了使用版本控制而增加更多额外的支出。

之前,我只提到过git作为(D)VCS。但是,既然这个项目是Python写的,Mercurial也是一个基于Python的不错的选择。因为两者都比较流行,所以你能找到许多在线学习资源。确保你已经安装了git或者Mercurial。两者都可以通过你的distro's packaging系统获取它们。

如果你打算用git,GitHub显然是一个很好的选择可以把你的代码保存到远程仓库里。使用Mercurial的话, Atlassian的Bitbucket是一个不错的选择(它也支持git,所以你用git或者Mercurial都行)

(源码)控制你的环境

即使我们还没真正做什么,但我们知道我们想让所有东西都在源码控制下。我们有两类“东西”将提交:你的代码本身(包括模板,等等)和支持文件,像数据库夹具、South迁移(以后会更多)和requirements.txt文件,列出你的项目依赖的所有包,允许自动构建环境(不需要再次使用pip install安装所有包)。

让我们开始创建我们的项目文件夹。使用django-admin.py提供的startproject命令来设置。

$ django-admin.py startproject django_project

我们将看到创建了一个单独的文件夹:django_project。在django_project文件夹内,我们将看到 另一个包含了常见元素的django_project文件夹:setting.py,urls.py和wsgi.py。在第二个django_project文件夹的同一级内有manage.py文件。

插曲:项目vs.应用程序

你也许会好奇,在Django1.4中,为什么已经有了新建应用程序的命令还要增加新建项目的命令。答案在于Django“项目”和Django“应用程序”的区别。简单来说,一个项目是一套完整的网站或者应用。一个“应用程序”是一个可以用在任何Django项目中的很小的、(希望是)独立的Django应用。如果你正在构建一个叫做“超级博客”的博客应用,那么“超级博客”就是你的Django项目。如果“超级博客”支持读者投票,那“投票”就是被“超级博客“使用的一个Django应用程序。这个概念就是需要你的投票应用程序可以应用在其他需要用户投票的Django项目中,而不是仅能应用在”超级博客“项目中。一个项目就是一堆应用程序按照项目特定的逻辑构建的一个集合。一个应用程序可以应用在多个项目中。

尽管你会本能地倾向于在你的“投票”应用程序中包含大量"超级博客"的特定代码和信息,但避免这样有许多好处。基于松耦合的原理,将你的应用编写为一个独立的实体可以保持设计意图,并且可以避免项目里的bug直接影响到你的应用。这也意味着,如果你希望的话,你可以把你的任何应用程序发给另一个开发者,且他们不需要访问或更改你的主项目。

像软件开发中的许多事情一样,这需要一点付出,但回报很丰厚。

创建仓库

现在我们的项目里已经有一些“代码”了(确实来说只是一些股票脚本和空的配置文件,恕我这样说),现在是我们初始我们源码控制库再好不过的时间了。下面是在Git和Mercurial中实现的步骤。
git

$ git init

这条命令在当前目录创建了一个git仓库。将我们所有的文件添加到git以便提交。

$ git add django_project

现在,我们将代码切实提交到我们的新库中:

$ git commit -m 'Initial commit of django_project'

Mercurial

$ hg init

这条命令在当前目录创建了一个Mercurial仓库。将我们所有的文件添加到git以便提交。

$ hg add django_project

现在,我们将代码切实提交到我们的新库中:

$ hg commit -m 'Initial commit of django_project'

如果你打算使用像GitHub或者Bitbucket,现在是时候把代码push上去了。

使用South进行数据库迁移

Django中最令人沮丧的特性之一是管理模型的变化和数据库的相关变化。有了South的帮助,你可以实现创建一个完整的应用,而不需要写具体的数据库代码。South会创建一个迁移文件来检测你的模型变化,并自动在数据库中生成。这使得你既可以前向根据最新变化来迁移数据库,又可以后向取消一个变化或者一系列变化。它让你的生活如此简单,Django发行版没有包含它真让人吃惊。

何时开始使用South

在前面的文章中,我建议在项目的一开始就使用South。对于相对简单的项目而已,这挺好。然而,如果在你的原型中有大量的模型有很大的变化,那现在不是使用South的时候。对应的,仅仅丢掉并在需要时重建数据库。你可以编写脚本来构成拥有一些测试数据的数据库,并在需要时编辑它们。然而,一旦你的模型不再变化,尽快开始使用South。这很简单:

./manage.py convert_to_south <app_name>

安装和设置

仍然在我们的虚拟环境下,像这样安装South:

$ pip install south

我们在项目的settings.py文件中把South添加到INSTALLED_APS中。现在就添加,包括你的项目中的数据库设置,然后运行python manage.py syncdb。你将需要提升权限使用超级用户名和密码(你可以输入然后回车)。更重要的是,South已经在数据库中设置好了它需要用的表格。

你可能认识到我们并没有在项目中添加应用,而只是运行了 syncdb。先这样做可以让 South 在一开始的时候就被安装。使用 South,在我们应用中的所有迁移工作都可以完成,包括初始迁移。

由于我们刚刚完成了很多变更,现在将是一个提交的好时间。你得适应频繁的提交,要知道,提交的粒度越小,在出错时回退的自由度越高。

要进行提交操作,让我们看看都有那些修改。

(git)

$ git status
# On branch master
# Changes not staged for commit:
#  (use "git add <file>..." to update what will be committed)
#  (use "git checkout -- <file>..." to discard changes in working directory)
##    modified:  django_project/settings.py
## Untracked files:
#  (use "git add <file>..." to include in what will be committed)
##    django_project/.settings.py.swp
#    django_project/__init__.pyc
#    django_project/settings.pyc

(Mercurial)

$ hg status
M django_project/django_project/settings.py
? django_project/django_project/.settings.py.swp
? django_project/django_project/__init__.pyc
? django_project/django_project/settings.pyc

使用 git 和 Mercurial,你可能发现一些你永远都不希望提交的文件,例如上面出现的   python 编译 后的 .pyc 文件,以及 vim 的.swp 交换文件。要忽略这些文件,在项目的根目录中创建一个 .gitignore 或 .hgignore 文件,并在其中添加匹配你不希望追踪的文件的 shell 模式。例如,我的文件内容多半就是:
?

代码如下:

*.pyc.*swp

在我们提交之前,还有一个信息需要查看:我们已经安装的 Python 包。我们希望能够追踪使用到的 Python 包的名称和版本,这样一来,我们就可以轻松的重建生产环境。pip 正好有个命令可以完成我们这个需求。

$ pip freeze > requirements.txt

我将 pip 的输出存入名为 requirements.txt 的文件,并将这个文件添加到代码控制中。这样,我们总是拥有一个更新的列表,里面包含了将使用的包。

现在将 settings.py 及 requirements.txt 添加到提交文件中,并提交:

$ (git/hg) add django_project/settings.py requirements.txt
$ (git/hg) commit -m 'Added South for database migrations'

新型设置

随着开发者对Django和Python越来越舒适,他们会发觉settings.py就是个简单的Python脚本,因此可以“编写”。对settings.py的一个常见方式是从一个颇为古怪的项目文件夹移动到一个新的叫做conf或者config的文件夹。要清楚你需要对manage.py做些小改变来适应这个移动。

在setting.py内,INSTALLED_APPS会很快变成一堆第三方的包,自身django应用和项目特定的应用。我习惯把INSTALLED_APPS分成三个类别:

  1. DEFAULT_APPS:作为默认Django安装(像admin)的一部分的Django框架应用
  2. THIRD_PARTY_APPS:像South
  3. LOCAL_APPS:你创建的应用

这可以更容易的看出哪些是你使用的第三方应用,哪些是项目自身的。仅仅记住最后有一行和下面相似的代码:

INSTALLED_APPS = DEFAULT_APPS + THIRD_PARTY_APPS + LOCAL_APPS

否则,Django将会出现没有定义INSTALLED_APPS的错误。

创建我们的应用

以正常的方式使用manage.py来创建一个应用(python manage.py startapp myapp),并把它加入到INSTALLED_APP中。同时,花费时间让manage.py可执行(chmod +x manage.py),这样你就可以仅仅输入./manage.py <command>,而不需要总是输入python manage.py <command>。老实说,很少有开发者这么做。我无法搞清楚为什么。

在添加模型前,我们要做的第一件事是我们告诉South我们想用它做迁移:

$ python manage.py schemamigration myapp --initial

这将创建一个移植文件,用来应用我们对于数据库的模型更改(如果我们有的话),而不需要完全销毁再重建它。当情况偏离时,它也可以让我们用来 恢复更改。我们使用移植文件来 移植数据库的变化(即使还没有变化),命令如下:

$ python manage.py migrate myapp

South足够智能,知道去哪里找到移植文件,也记得我们做的最后的移植。你可以指定单独的移植文件,但这一般并不是必须的。

当我们最终对模型做出改变时,我们使用下面的命令来让South创建一个移植文件:

$ python manage.py schemamigration myapp --auto

这将检测myapp中的模型,并自动相应的添加、删除或修改数据库中的表。然后使用如上的移植命令就可以将改变应用到数据库上。

开发区域

还有一件事你需要注意:将开发区域与你已经确认的文件区分开,原因显而易见。使用Git和Mercurial实现这个很简单,而且也有助于部署。创建django_project所在目录之外的一个目录作为你开发区域(我把它叫做dev)。

在你的开发目录,使用git或Mercurial克隆当前项目:

$ (git/hg) clone /path/to/my/project/

两个工具都将创建库的一份完整拷贝。所有的更改、分支及历史都将在新库中可用。从现在起,你应该在你的开发目录工作。

由于使用Git和Mercurial来进行分支都容易便捷,当你切换新分支或站点的大规模变化时创建分支。下面是两个工具的实现方法:
(git)

$ git checkout -b <branchname>

这不仅创建了一个命名新分支且会将代码检出。几乎所有的开发工作都应该在分支上,这样主分支可以随时恢复。
(Mercurial)

$ hg branch <branchname>

请注意,在Mercurial社区里分支是一个有争议的话题,目前这里有一些可用的选项,但其中还没有“显然正确”的。在这里,我使用命名分支,这可能是最安全且最有益的分支风格。任何在branch命令后的提交将在新分支生效。

使用 Fabric 来进行部署

那么我们就有了一个Django应用。我们怎么来部署它呢?Fabric。对一个合理大小的项目来说,讨论任何其它的东西都是浪费时间。Fabric可用于许多种不同目的,不过在部署方面它确实很出色。

$ pip install fabric

Fabric 需要一个名为fabfile.py的 fabfile 文件,这个文件定义了所有我们可以采用的动作。现在我们就来创建它。将下面这些内容写入fabfile.py并将其放到项目的根目录。

from fabric.api import localdef prepare_deployment(branch_name):
  local('python manage.py test django_project')
  local('git add -p && git commit') # or local('hg add && hg commit')

这样就会运行这个测试并提交你的变更,但是提交只在测试通过的条件下发生。在此处,生产环境中一个简单的"pull"动作都可以成为实际部署。我们给实际部署再增加一些东西。将以下内容增加到fabfile.py:

当前1/2页 12下一页阅读全文

(0)

相关推荐

  • 在Python的Django框架中用流响应生成CSV文件的教程

    在Django里,流式响应StreamingHttpResponse是个好东西,可以快速.节省内存地产生一个大型文件. 目前项目里用于流式响应的一个是Eventsource,用于改善跨系统通讯时用户产生的慢速的感觉.这个不细说了. 还有一个就是生成一个大的csv文件. 当Django进程处于gunicorn或者uwsgi等web容器中时,如果响应超过一定时间没有返回,就会被web容器终止掉,虽然我们可以通过加长web容器的超时时间来绕过这个问题,但是毕竟还是治标不治本.要根本上解决这个问题,Py

  • Python的Django框架使用入门指引

     前言 传统 Web 开发方式常常需要编写繁琐乏味的重复性代码,不仅页面表现与逻辑实现的代码混杂在一起,而且代码编写效率不高.对于开发者来说,选择一个功能强大并且操作简洁的开发框架来辅助完成繁杂的编码工作,将会对开发效率的提升起到很大帮助.幸运的是,这样的开发框架并不少见,需要做的仅是从中选出恰恰为开发者量身打造的那款Web框架. 自从基于 MVC 分层结构的 Web 设计理念普及以来,选择适合的开发框架无疑是项目成功的关键性因素.无论是 Struts.Spring 或是其他 Web 框架的出现

  • Python中DJANGO简单测试实例

    本文实例讲述了Python中DJANGO简单测试的用法.分享给大家供大家参考.具体如下: 这里以facebook台湾的测试版为例. 仅仅测试用户登录,主要说明测试的使用和django环境的设置. 代码如下: import os import sys import unittest import hashlib TEST_MEMBER_ID = 11 SNS_ID = 100002309745702 TEST_SESSION_KEY = '125737724171219|2.AQCp7ctCYXJ

  • 详解Python的Django框架中的通用视图

    通用视图 1. 前言 回想一下,在Django中view层起到的作用是相当于controller的角色,在view中实施的 动作,一般是取得请求参数,再从model中得到数据,再通过数据创建模板,返回相应 响应对象.但在一些比较通用的功能中,比如显示对象列表,显示某对象信息,如果反复 写这么多流程的代码,也是一件浪费时间的事,在这里,Django同样给我们提供了类似的 "shortcut"捷径--通用视图. 2. 使用通用视图 使用通用视图的方法就是在urls.py这个路径配置文件中进

  • 利用Python的Django框架中的ORM建立查询API

     摘要 在这篇文章里,我将以反模式的角度来直接讨论Django的低级ORM查询方法的使用.作为一种替代方式,我们需要在包含业务逻辑的模型层建立与特定领域相关的查询API,这些在Django中做起来不是非常容易,但通过深入地了解ORM的内容原理,我将告诉你一些简捷的方式来达到这个目的. 概览 当编写Django应用程序时,我们已经习惯通过添加方法到模型里以此达到封装业务逻辑并隐藏实现细节.这种方法看起来是非常的自然,而且实际上它也用在Django的内建应用中. >>> from djang

  • 使用Python的web.py框架实现类似Django的ORM查询的教程

    Django中的对象查询 Django框架自带了ORM,实现了一些比较强大而且方便的查询功能,这些功能和表无关.比如下面这个例子: class Question(models.Model): question_text = models.CharField(max_length=200) pub_date = models.DateTimeField('date published') >>> Question.objects.all() >>> Question.ob

  • Python使用django获取用户IP地址的方法

    本文实例讲述了Python使用django获取用户IP地址的方法.分享给大家供大家参考.具体如下: 函数实现: def get_client_ip(request): try: real_ip = request.META['HTTP_X_FORWARDED_FOR'] regip = real_ip.split(",")[0] except: try: regip = request.META['REMOTE_ADDR'] except: regip = "" r

  • 全面剖析Python的Django框架中的项目部署技巧第1/2页

    项目开始时是一个关键时刻,选择会对项目产生长期的影响.有很多关于如何开始使用Django框架的教程,但很少讨论如何专业地使用Django,或如何使用行业公认的最佳做法来确保你的项目规模的持续增长.事前的筹划让你(和所有同事的生活)在走向将来时更容易. 文章结束时,你将有 一个全功能的Django 1.6项目 源代码受控的所有资源(使用Git或Mercurial) 自动回归和单元测试(使用unittest库) 一个独立于特定环境的安装项目(使用virtualenv) 自动化的部署和测试(使用Fab

  • 对Python的Django框架中的项目进行单元测试的方法

     Python中的单元测试 我们先来回顾一下Python中的单元测试方法. 下面是一个 Python的单元测试简单的例子: 假如我们开发一个除法的功能,有的同学可能觉得很简单,代码是这样的: def division_funtion(x, y): return x / y 但是这样写究竟对还是不对呢,有些同学可以在代码下面这样测试: def division_funtion(x, y): return x / y if __name__ == '__main__': print division

  • Python的Django框架中的Context使用

    一旦你创建一个 Template 对象,你可以用 context 来传递数据给它. 一个context是一系列变量和它们值的集合. context在Django里表现为 Context 类,在 django.template 模块里. 她的构造函数带有一个可选的参数: 一个字典映射变量和它们的值. 调用 Template 对象 的 render() 方法并传递context来填充模板: >>> from django.template import Context, Template &

  • 在Python的Django框架中创建和使用模版

    如何使用模板系统 让我们深入研究模板系统,你将会明白它是如何工作的.但我们暂不打算将它与先前创建的视图结合在一起,因为我们现在的目的是了解它是如何独立工作的. . (换言之, 通常你会将模板和视图一起使用,但是我们只是想突出模板系统是一个Python库,你可以在任何地方使用它,而不仅仅是在Django视图中.) 在Python代码中使用Django模板的最基本方式如下: 可以用原始的模板代码字符串创建一个 Template 对象, Django同样支持用指定模板文件路径的方式来创建 Templa

  • Python的Django框架中if标签的相关使用

    {% if %} 标签检查(evaluate)一个变量,如果这个变量为真(即,变量存在,非空,不是布尔值假),系统会显示在 {% if %} 和 {% endif %} 之间的任何内容,例如: {% if today_is_weekend %} <p>Welcome to the weekend!</p> {% endif %} {% else %} 标签是可选的: {% if today_is_weekend %} <p>Welcome to the weekend!

  • 在Python的Django框架中为代码添加注释的方法

    就像HTML或者Python,Django模板语言同样提供代码注释. 注释使用 {# #} : {# This is a comment #} 注释的内容不会在模板渲染时输出. 用这种语法的注释不能跨越多行. 这个限制是为了提高模板解析的性能. 在下面这个模板中,输出结果和模板本身是 完全一样的(也就是说,注释标签并没有被解析为注释): This is a {# this is not a comment #} test. 如果要实现多行注释,可以使用`` {% comment %}`` 模板标

  • 详解在Python的Django框架中创建模板库的方法

    不管是写自定义标签还是过滤器,第一件要做的事是创建模板库(Django能够导入的基本结构). 创建一个模板库分两步走: 第一,决定模板库应该放在哪个Django应用下. 如果你通过 manage.py startapp 创建了一个应用,你可以把它放在那里,或者你可以为模板库单独创建一个应用. 我们更推荐使用后者,因为你的filter可能在后来的工程中有用. 无论你采用何种方式,请确保把你的应用添加到 INSTALLED_APPS 中. 我们稍后会解释这一点. 第二,在适当的Django应用包里创

  • 介绍Python的Django框架中的QuerySets

    Django的QuerySets酷毙了! 在本文中我将解释一下QuerySets是什么,它是如何工作的(如果你对它已经熟悉了,你可以直接跳到第二部分),我认为如果可以的话你应该总是返回QuerySets对象,下面让我来谈谈如何做. QuerySets很酷 QuerySet,本质上是一个给定的模型的对象列表.我说"列表"而不是"组"或更正式的"集合"因为它是有序的.事实上,你可能已经熟悉如何获得QuerySets,因为这就是你调用variousBo

  • 详解Python的Django框架中manage命令的使用与扩展

    [简介] django-admin.py是Django的一个用于管理任务的命令行工具.本文将描述它的大概用法. 另外,在每一个Django project中都会有一个manage.py.manage.py是对django-admin.py的简单包装,它额外帮助我们做了两件事情: 它将你的project的包放到sys.path中 它将DJANGO_SETTINGS_MODULE环境变量设置为了你的project的setting.py文件的位置. 如果你是通过setup.py工具来安装Django的

  • Python的Django框架中设置日期和字段可选的方法

    设置字段可选 在摆弄了一会之后,你或许会发现管理工具有个限制:编辑表单需要你填写每一个字段,然而在有些情况下,你想要某些字段是可选的. 举个例子,我们想要Author模块中的email字段成为可选,即允许不填. 在现实世界中,你可能没有为每个作者登记邮箱地址. 为了指定email字段为可选,你只要编辑Book模块(回想第五章,它在mysite/books/models.py文件里),在email字段上加上blank=True.代码如下: class Author(models.Model): f

随机推荐