Django项目布局最佳实践
Contents
什么是django应用,settings,以及各种相关联的目录的最佳布局方式? Django1.4版本以后更新了默认的项目布局,这项工作花费了很长时间,但是现在还有更好建议可以使它变的更好。
关于这个问题,我们将结合我们的实际经验来进行探讨。这些布局实践是在django1.7.1版本下进行的,但是同样适用于1.4之后的版本。
为什么这种布局方式相比是更好的
我们推荐的项目布局有以下优点:
1.允许你将项目中的app进行分离,重新打包,然后重用到其他别的项目中去。当你新建一个app的时候,你不清楚它是否可以重用,但以这种布局方式,当你想要把它重用到其他地方的时候,会省事很多。 2.鼓励设计出更有利于重用的app 3.细化的环境配置。在单一的settings中没有 if DEBUG == True 这样无用的话。 有个basic的基础配置文件,其他配置文件都是在此基础上进行重载。 4.细化的requirements依赖 5.项目级别的template和staic files,如果需要的话,可以覆盖默认的app级别 6.更小而且细化的测试文件,易于阅读和理解。
确保你有两个app,一个是blog,一个是users,两种环境,dev和prod 项目布局结构如下:
|
|
下面介绍怎么样把一个项目改为这种布局,以及解释这样做的好处。
目前的项目布局:
这里的项目名foo。如果你执行
|
|
你会得到如下的目录结构
|
|
在这里,我们有个顶层的目录foo,包含了manage.py和项目目录foo/foo。
修改Settings
这里我们去修改你糟糕的settings文件。我们这里展示了一种布局,我很惊奇很少有人知道可以这样做。我把它归咎于,人们只知道settings是python代码,但是却没有把它当做python代码看待。
我们这里有4种环境下分别对应的settings文件,dev, stage, jenkins, production。
配置步骤如下: 1.在foo/foo目录下,新建一个名为settings的目录,并且创建一个空的__init__.py文件。 2.将foo/foo/settings.py 移动到 foo/foo/settings/base.py 3.创建独立的dev.py, stage.py, jenkins.py, prod.py。 这四个新建的py文件 应该包含如下代码:
|
|
在本地开发环境下,我们想要DEBUG=True, 但是有时候,会不小心在生产环境下,将DEBUG模式打开,为了避免这种情况,我们只需要在foo/foo/settings/prod.py下新增DEBUG=False。
这里这样做实际上是,相当于是重载。
还有哪些其他可以适配的? 还有一点是,在staging,jenkins,和production环境下,往往需要指向不同的数据库,甚至是不同hosts下的数据库。 所以,在不同的环境中,各自适配即可。
使用上述的settings文件
使用上述settings文件是容易的,无论以哪种方式 比如: 在wsgi.py中可以这样设置
|
|
可能,你想用在命令行选项下:
|
|
如果你使用gunicorn
|
|
settings下还有哪些可以适配?
另一个比较有用的tip是,修改一些默认设置从不可修改的元组,改为可以修改的列表。 以INSTALLED_APPS为例:
|
|
修改为
|
|
这样,我们可以在不同的环境下,新增或者删除INSTALLED_APPS中的选项了。 比如,我们只希望django-debug-toolbar安装在dev环境,而不是其他环境下。 这个技巧也被用在TEMPLATE_DIRS和MIDDLEWARE_CLASSES设置中。
另一个有用的技巧是,我们经常用来,将apps分为连个lists,一个作为prerequisites 另一个作为实际项目app。示例如下:
|
|
为什么这是有用的?一个原因是,便于区分,django核心app,第三方app,和你自己项目内部的app。 ROJECT_APPS用来保存你自己项目内部的app,通常还被用来测试代码和检查代码覆盖。 通过PROJECT_APPS,你可以容易并且自动的,确保它们的测试代码在运行,代码覆盖被记录。
修正requirements文件
很多人有单独的requirements.txt文件,它们通常用来安装依赖,命令行代码如下:
|
|
对于小的项目来说,它足够用了。但是有一个技巧是,你可以在一个requirements文件中用-r来包含其他requirements文件。 比如我们可以有一个名为base.txt文件,并且我们在测试环境下,有一个requirements/test.txt文件,它的内容如下:
|
|
我承认,这不是一个作用非常大的修改。但是它帮助我们分离了不同环境下的依赖配置。 比较有用的一点是,它减少了production环境下,pip安装的时间,因为可以避免安装开发环境下需要,但是production下不需要的依赖。
测试文件
为什么需要分离我们的测试文件? 主要的原因在于,如果你把测试都放在一个单独的test.py中,每个app最终会变得臃肿,难以测试,可读性变差。
当你和其他开发者合作开发的时候,你会减少很多代码合并的冲突(对于同一个文件,多人改动,容易造成代码冲突)
URLS
对于比较小的项目来说,可以把所有的url路由都配置到foo/urls.如果考虑可读性,重用性,建议在每个app里面都单独设置url.py,然后以incldue的方式包括项目的主url.py中。 不好的:
|
|
好的:
|
|
模板和静态资源
在每个app下设置templates/和static/目录,可以帮助将app重用到别的项目中去。
通常情况下,app查找文件时,会默认加载app/templates下的模板,和app/static下面的静态文件
但是,我们可以从项目foo/tempaltes下覆盖掉app下面的模板。比如,templates/blog/detail.html会覆盖掉 blog/templates/blog/detail.html下面的模板。
适用于,比如说,我们引入了第三方的app,但是对第三方的模板不满意,需要做一些修改的情况
重用django app
假设你已经用这种布局一段时间了,你的新项目site中也需要一个类似blog的东西,你发现你的foo项目下的blog正好可以满足需求。 所以,你就把foo下面的blog代码粘贴复制到了你的新项目site中。 但是,这样做是不对的。因为,比如说你的foo下面的blog有bug或者新特性增加,你必须手动地把它移动到新项目site中。
相反,你应该为你的blog单独新建一个repo,并且把你的foo/blog放到其中。然后在你的现有项目和新项目中通过pip来安装。
此处的意思也就是通用的app,可以做成一个第三方的app,便于管理。
维护和更新的话,交与第三方app的作者负责就好啦。
你仍然可以在项目级别上,覆盖掉template模板和static资源,这样做没有什么问题。
同样的道理,不要尝试去修改第三方app的源码
其他资源:
cookiecutter-django可以用于快速构建django项目布局 django最佳实践的书籍推荐: Two Scoops of Django: Best Practices For Django
原文章出处:http://www.revsys.com/blog/2014/nov/21/recommended-django-project-layout/
Author tmackan
LastMod 2016-09-12