Django-Extensions 文档¶
Django Extensions 是Django框架的扩展功能集合.
包括management命令扩展,数据库字段扩展,admin后台扩展等.
译者注: 文档中包含了部分 git , github , Python env 相关内容, 阅读时遇到相关只是请参考相应文档.
开始¶
了解Django Eextensions最简单的方式是查看 excllent screencast by Eric Holscher .只要几分钟的时间, Eric就能帮助你了解一半的扩展命令是做什么用的.
安装¶
使用 pip
安装 django-extensions
:
$ pip install django-extensions
还可以从github上下载源码安装:
$ git clone git://github.com/django-extensions/django-extensions.git
$ cd django-extensions
$ python setup.py install
更多安装细节,查看 安装django-extensions.
Python以及Django的兼容性¶
django-extensions
尽量根据Django版本发布计划支持相应的Django和Python版本 参考Django版本支持说明 [1] .
新版本的 django-extensions
可能在旧版本的Django或Python中也会正常运行,但是我们已经放弃修复与旧版本Django或Python的兼容性bug.
目前支持的Python版本是 2.7, 3.4, 3.5, pypy, pypy3. 支持的Django版本是1.8, 1.9.
目录¶
安装django-extensions¶
概要: | 安装django-extensions |
---|
安装¶
给 django-extensions 贡献代码¶
django-extensions 代码托管在github:
https://github.com/django-extensions/django-extensions
克隆项目后就可以修改源码
开发版本中的 django command extensions 已经十分稳定, 并能够让你更新到最新的修复代码.
安装开发版本的代码:
$ pip install -e git+https://github.com/django-extensions/django-extensions.git#egg=django-extensions
然后在 src/django-extensions 目录下可以看到源码
并且在你的PYTHONPATH环境变量中已经可以使用django-extensions了. 打开命令行, 检查一下是否可用:
>>> import django_extensions
>>> django_extensions.VERSION
(0, 8)
注意: 这种版本的代码会和正式发布的代码有些不同. 可能包含未知bug和兼容性问题, 但总体来说, 还是值得一试的.
在Django中使用¶
在Django项目的配置文件中,把 django_extensions 添加到 INSTALLED_APPS
列表中:
INSTALLED_APPS = (
...
'django_extensions',
)
这样就可以在Django的命令行中使用 django-extensions
提供的扩展命令了.
再次运行 ./manage.py help 命令时,就可以看到新的命令.
有些新增的命令依赖其它程序或Python库,例如 [1]
- ‘export_emails’ 需要 python vobject 模块来创建vcard文件
- ‘graph_models’ 需要 pygraphviz 库来渲染图片文件.
如果执行的django-extensions命令依赖的程序或库没有安装(或不在当前的环境中),那么这条命令被执行时会抛出异常,并提示缺少的依赖程序或库.
[1] | vcard是电子名片的格式 |
management 命令扩展¶
概要: | management扩展命令列表 |
---|
- shell_plus - Django shell的加强版. 自动载入所有app的models,可以方便的使用这些ORM.
admin_generator
- 提供app名字后, 自动生成Admin类. 生成的代码会输出到标准输出中(STDOUT).clean_pyc
- 清除项目编译后产生的全部python的二进制文件- create_app - 新建一个app的简便方法,可以通过
--template
参数指定一个app作为创建模板 [1]. create_command
- 在指定app内创建一个命令扩展目录,方便添加新的扩展命令(或者只能手动创建扩展命令的目录).create_template_tags
- 在制定的app内创建模板标签目录create_jobs
- 在指定app内创建一个定时任务扩展目录,可以定期执行指定任务.clear_cache
- 清除缓存, 在测试和部署过程中十分有用.compile_pyc
- 编译项目, 并生成python二进制文件.describe_form
- 显示针对一个model的form描述.复制输出的内容到forms.py中可以完整定义一个对应model的form.- 删除优化后多余的migrations - 删除冗余的migration文件. migrstion文件在合并优化之后遗留下来的冗余文件是没有用的, 直接删除.
- dumpscript - 生成一个Python脚本.包含指定app的所有数据对象.与Django的
dumpdata
命令不同的是dumpscript
导出的是Python对象,而不是纯数据.这种导出数据的方式比直接导出数据或XML文件更容易理解,也更灵活. - export_emails - 从用户表中导出联系人信息,支持多种导出格式: Address, Google, Outlook, LinkedIn和 VCard.
find_template
- 根据给定的模板名称, 查找他的文件路径generate_secret_key
- 重新生成一个项目密钥,settigns.py
文件中的 SECRET_KEY 配置.- graph_models - 生成一个 GraphViz 文件.将输出内容写入一个文件.以图形化数据模型.传入多个app的名字作为参数,可以在一个文件中显示多个模型的图形化格式 [3].
mail_debug
- 开启一个邮件服务, 将Django项目发出的邮件从控制台输出, 而不是真的发送出去.notes
- 显示python文件和HTML文件中的全部重要备注 比如 TODO, FIXME, BUG, HACK, WARNING, NOTE 和 XXXpasswd
- 重新设定某个用户的密码,用法: ./manage.py passwd [用户名] .pipchecker
- 扫描pip依赖文件 [3] 并找出需要更新的包. 类似于pip list -o
命令安装依赖包的过程(在虚拟环境中 virtualenv), 只不过它是通过pip依赖文件实现的.- print_settings - 与
diffsettings
命令功能类似,但会根据参数显示指定的配置,如果不传参数默认显示的全部配置. print_user_for_session
- 通过session key
来查看当前用户信息,这个方法在查找哪个用户行为导致程序异常非常有帮助. 仅在SESSION_ENGINE
设置为'django.contrib.sessions.backends.db'
(默认值)的时候才能正常工作drop_test_database
- 删除测试数据库. 在自动化测试/部署系统(BuildBot, Jenkins, 等等)中十分有用. 确保测试数据库最终会被清除掉.reset_db
- 重置数据库 (目前支持 sqlite3, mysql, postgres),可以用来删除或创建数据库.runjob
- 执行一个单独的任务,是django-extensions
任务系统中的一个功能.runjobs
- 按计划定期执行任务. 按 小时,天,周,月执行. 时间计划功能是系统任务的一部分.runjobs
- 执行计划任务. 分为按小时执行,按天执行,按周执行,按月执行.是django-extensions
任务系统中的一部分功能.- runprofileserver - 在启动
runserver
测试服务的同时,其用profile
功能,可以记录服务的详细日志,包含了对于Python方法的详细执行分析.在服务器性能分析时,这是最佳方法了. - runscript - 在当前项目的环境下执行脚本.
- runserver_plus - 在Werkzeug debugger模式下开启服务. 需要安装 Werkzeug. 这是个杀手级应用.
set_fake_emails
- 根据每个用户的名称, 给所有用户生成一个邮箱, 默认格式为(“%(username)s@example.com”). 生成邮箱的可选参数有: username, first_name, last_name. 仅用于测试set_fake_passwords
- 将所有用户的密码设置为一个统一值 (默认密码). 一定要在测试环境下使用.show_template_tags
- 显示当前项目可用的模板标签和过滤器.show_urls
- 统一显示项目中包含的所有url.- sqldiff - 显示app的models与数据库中的表的差别.这个功能非常好用,但还处于实验阶段,虽然不能捕获所有异常,但能很好的检查出不同的内容 [4][4]_.
- sqlcreate - 根据配置文件的内容,生成创建数据库表的SQL语句.
- sqldsn - 从Django的配置文件中读取数据库连接参数. 可以提供给其它系统使用.
- sync_s3 - 将settings.MEDIA_ROOT目录中文件复制到S3中.可以通过参数设置否是使用gzip压缩,文件编码,文件的缓存时间等.
syncdata
- 把fixture(s)中的数据同步到数据库中, 一条不多, 一条不少.unreferenced_files
- 输出所有在 MEDIA_ROOT 路径下, 但是数据库中没有引用的文件名称.update_permissions
- 根据参数, 重载指定apps的权限. 如果没有参数, 则重载全部apps的权限.validate_templates
- 检查模板中可能存在的语法错误和变异错误.set_default_site
- 通过 name 和 domain 或者 system-fqdn`参数来设置默认站点 `django.contrib.sites 的参数.
[1] | Django1.6版本也开始支持通过模板创建app, 参考 https://docs.djangoproject.com/en/1.6/ref/django-admin/#startapp-appname-destination |
[3] | (1, 2) 类似MySQL的relationship map, 将models的关系以描述方式输出,虽然是文本描述,但是使用了GraphViz格式,可以打开成图形 |
management 下一步计划的功能¶
概要: | 这是扩展命令的计划功能, 在未来版本中会得到支持 |
---|
- 创建app的
form
和manager
- CSS和JS文件的合并压缩功能
译者注: django-extensions 的新命令增加的功能会依照目前项目的需要.Django版本在演化过程中逐渐增加了很多很有用的命令.CSS和JS文件的合并压缩功能对于某些项目可能并不需呀,因为我们可以在Django项目中包含自己的静态文件解决方案,比如百度的FIS
Admin 后台管理扩展¶
概要: | Admin后台的字段扩展 |
---|
ForeignKeyAutocompleteAdmin - 该扩展字段在Admin后台中显示为一个搜索输入框. 前端显示的内容由 ForeignKeySearchInput form的weight渲染, 通过jQuery的autocompletion功能实现搜索效果.
用法举例¶
启用后台管理的自动补全功能,根据示例编辑 admin.py
文件:
from django.contrib import admin
from foo.models import Permission
from django_extensions.admin import ForeignKeyAutocompleteAdmin
class PermissionAdmin(ForeignKeyAutocompleteAdmin):
# User is your FK attribute in your model
# first_name and email are attributes to search for in the FK model
related_search_fields = {
'user': ('first_name', 'email'),
}
fields = ('user', 'avatar', 'is_active')
...
admin.site.register(Permission, PermissionAdmin)
如果使用了 django-reversion ,参考下面的例子:
from django.contrib import admin
from foo.models import MyVersionModel
from reversion.admin import VersionAdmin
from django_extensions.admin import ForeignKeyAutocompleteAdmin
class MyVersionModelAdmin(VersionAdmin, ForeignKeyAutocompleteAdmin):
...
admin.site.register(MyVersionModel, MyVersionModelAdmin)
如果想要限制搜索功能中的自动匹配, 覆写admin的 get_related_filter
方法.
例如, 添加一条限制给非管理员用户: 仅能向自己创建的文章中添加附件
class AttachmentAdmin(ForeignKeyAutocompleteAdmin):
...
def get_related_filter(self, model, request):
user = request.user
if not issubclass(model, Article) or user.is_superuser():
return super(AttachmentAdmin, self).get_related_filter(
model, request
)
return Q(owner=user)
注意, 某些恶意操作可以绕过这种使用限制(例如一个经过精心构造的伪装请求)
shell_plus¶
概要: | shell命令的扩展命令,运行Django shell的同时自动加载所有app的models,并选择使用Python shell的版本. |
---|
交互式的 Python Shells¶
shell_plus支持不同类型的Python shell.
IPython:
$ ./manage.py shell_plus --ipython
bpython:
$ ./manage.py shell_plus --bpython
ptpython:
$ ./manage.py shell_plus --ptpython
Python:
$ ./manage.py shell_plus --plain
默认shell优先顺序是: ptpython, bpython, ipython, python.
也可以在 settings.py
配置中指定优先选择的shell工具:
# 在shell_plus中使用ipython作为交互工具
SHELL_PLUS = "ipython"
还可以使用 IPython Notebook, 用浏览器作为Python的shell环境
$ ./manage.py shell_plus --notebook
IPython Notebooks交互终端可以在运行时更新, 也就是在Django项目中的代码出现修改后, 通过菜单中的 Kernel > Restart 可以更新运行时的环境.
配置¶
如果遇到apps中包含的的models名字出现冲突,或不想载入特定apps的models的情况,可以通过配置别名的方法解决:
提示: 下列配置仅在shell_plus中生效,不会影响当前项目运行的环境变量
# 将自动载入的Messages模块重命名为blog_messages
SHELL_PLUS_MODEL_ALIASES = {'blog': {'Messages': 'blog_messages'},}
# 自动载入的 myblog 模型添加前缀
SHELL_PLUS_APP_PREFIXES = {'blog': 'myblog',}
# 不加载sites app和pictures的blog模型
SHELL_PLUS_DONT_LOAD = ['sites', 'blog.pictures']
设置别名和声明不加载的配置可以同时使用.
当引用嵌套模块时, 比如 somepackage.someapp.models.somemodel , 不能添加包(package)和 models 的名字
举例来说:
SHELL_PLUS_DONT_LOAD = ['someapp.somemodel', ] # This works
SHELL_PLUS_DONT_LOAD = ['somepackage.someapp.models.somemodel', ] # This does NOT work
也可以通过命令行参数设置不加载的模块:
$ ./manage.py shell_plus --dont-load app1 --dont-load app2.module1
命令行的参数和配置文件中的设置是可以同时使用的,所以一次性的参数完全可以通过命令行运行,省去频繁修改配置文件的麻烦.
shell_plus还能使用 IPython Notebook .将浏览器作为交互的shell:
$ ./manage.py shell_plus --notebook
通过修改2个参数可以自定义 IPython 的行为.
第一个是 NOTEBOOK_ARGUMENTS
, 可以追加自定义参数, 需要通过下面方式启动:
$ ipython notebook -h
例如:
NOTEBOOK_ARGUMENTS = [
'--ip', 'x.x.x.x',
'--port', 'xx',
]
另一个参数是 IPYTHON_ARGUMENTS
,通过下面方式启动:
$ ipython -h
IPython Notebook
中也会将所有模块和models加载到全局变量中.
IPython NoteBook
中自动加载模块功能是通过参数配置的,默认为启用状态.:
--ext django_extensions.management.notebook_extension
自定义 IPython Notebook
配置需要覆盖Django项目的 IPYTHON_ARGUMENTS
配置:
IPYTHON_ARGUMENTS = [
'--ext', 'django_extensions.management.notebook_extension',
'--ext', 'myproject.notebook_extension',
'--debug',
]
想在 IPython Notebook
中启用自动加载功能,要么包含django-extensions默认的notebook扩展配置,要么把自动加载的代码拷贝到自定义的扩展中.
提示: IPython Notebook
的特性中不能识别 --dont-load
参数.
附加的引入模块¶
在配置文件中设置 SHELL_PLUS_PRE_IMPORTS
和 SHELL_PLUS_POST_IMPORTS
可以指定附加的引入模块.第一个配置中添加的模块会先于所有模块加载,第二个配置中添加的模块会后于所有模块加载.这两个配置的格式相同,在settings.py文件中添加:
SHELL_PLUS_PRE_IMPORTS = [
('module.submodule1', ('class1', 'function2')),
('module.submodule2', 'function3'),
('module.submodule3', '*'),
'module.submodule4'
]
上面的配置被转换为Python的引入代码结果,如下所示:
from module.submodule1 import class1, function2
from module.submodule2 import function3
from module.submodule3 import *
import module.submodule4
这些引入的变量在shell执行时就可以使用了.
数据库应用签名¶
使用PostgreSQL application_name
默认被设置为 django_shell
, 这样能够区分 shell_plus 下的查询语句.
SQL 查询¶
在 shell_plus 中可以输出生成SQL后的的查询语句
$ ./manage.py shell_plus --print-sql
也可以通过配置 SHELL_PLUS_PRINT_SQL 参数, 来实现相同的效果:
# print SQL queries in shell_plus
SHELL_PLUS_PRINT_SQL = True
create_app¶
概要: | 创建一个app的简要方法. |
---|
--template
参数指定使用一个模板来创建新的app.
--diagram
参数能够从 .dia
文件生成 models.py
和 admin.py
.
用法举例¶
例子需要在项目的根目录下执行,该目录下要包含 settings.py
文件 [1]
# 获取命令行的帮助
./manage.py create_app --help
# 从 [APP_NAME].dia 文件中生成 ``models.py`` 和 ``admin.py`` ,这个文件应该放在与 ``settings.py`` 相同的文件目录下
./manage.py create_app -d APP_NAME
从sample.dia文件生成app¶
./manage.py create_app --diagram=sample.dia webdata
-d
参数或 --diagram
参数通过 dia2django 生成models.py, 详细文档查看 django wiki.
译者注: 新版本Django原生命令 startapp
也提供了通过 --template
指定模板来创建app的功能
[1] | 这个说法不准确,Django1.4版本后就独立出了配置文件目录,settings.py文件不在项目根目录下.但是这不影响使用,因为项目配置文件是通过manage.py文件指定的. |
删除优化后多余的migrations¶
synopsis: | 把多个migrations文件优化到一个文件中, 多余的migrations文件就可以移除了 |
---|
通过替换属性来实现, 移除多个migrations文件优化到一个文件后遗留的多余的migrations文件.
这个自动化过程在 Django migration squashing documentation 中有更多描述. 这个功能会修改源码的文件结构, 小心使用.
用例¶
安装 django-extensions 后, 可以通过 delete_squashed_migrations 命令移除多余migrations文件.
# Delete leftover migrations from the first squashed migration found in myapp
$ ./manage.py delete_squashed_migrations myapp
# As above but non-interactive
$ ./manage.py --noinput delete_squashed_migrations myapp
# Explicitly specify the squashed migration to clean up
$ ./manage.py delete_squashed_migrations myapp 0001_squashed
dumpscript¶
概要: | 生成单独的Python脚本,包含指定app对应的数据库数据对象.可以用来将数据表导入数据库. |
---|
dumpscript
命令生成单独的Python脚本,包含了转换成Python对象的数据库数据.这种方法比直接创建数据库或通过XML创建数据库更容易理解,扩展性也更好.
为什么有这个功能¶
这样做的有几点好处:
- 数据库变更时会少出现些莫名其妙的错误: 不依赖ID的外键,会忽略掉新增和删除的列
- 编辑脚本后可以自动生成很多的实例数据
例如,编辑一个脚本,生成一些测试的初始数据到数据库中:
for i in xrange(2000):
poll = Poll()
poll.question = "Question #%d" % i
poll.pub_date = date(2001,01,01) + timedelta(days=i)
poll.save()
真实情况下数据库可能更大更复杂,通常是通过Admin后台生成一下测试数据,再导出脚本.编辑导出的脚本,得到更多的数据.
特性支持¶
- 外键和多对多关系(通过Python变量,而不是ID)
- 外键或多对多中对自己的引用
- models子类
- ContentType 字段类型, 并生成关联关系
- 递归引用
- 排除自增字段
- 父类不会被包含,除非没有子类继承它
- 可以引用单独的类
如何使用¶
从指定的app中导出所有models的建表语句:
$ ./manage.py dumpscript appname > scripts/testdata.py
导出指定模型的数据,添加参数 appname.ModelName
$ ./manage.py dumpscript appname.ModelName > scripts/testdata.py
清空指定app对应数据库数据,然后重新加载数据:
$ ./manage.py reset appname
$ ./manage.py runscript testdata
提示: runscript
命令只能执行在 scripts
模块下的脚本,所以要在 scripts
目录下创建 __init__.py 文件.
runscript¶
该要: | 在当前项目环境下执行脚本,这个功能非常有用,它能够允许在不启动Django服务的同时以Django项目的环境变量执行脚本方法. |
---|
开始使用¶
这个例子假设你跟着 Django1.8+ 版本的入门教程, 创建了 polls app,并包含``Question``模型. 我们将创建一个脚本, 从数据库中删除所有``Question``的数据.
首先要在项目根目录下创建一个脚本的目录,名字是 scripts
$ mkdir scripts
$ touch scripts/__init__.py
然后,创建一个想要执行的Python脚本:
$ touch scripts/delete_all_questions.py
这个脚本文件中必须包含 run()
方法, runscript
命令执行时会自动调用该方法.这个脚本中可以引用django项目中的任意模块或数据模型.
例如:
# scripts/delete_all_questions.py
from polls.models import Question
def run():
# Fetch all questions
questions = Question.objects.all()
# Delete questions
questions.delete()
提示: runscript
命令可以找到任意app下 scripts 目录中的脚本文件.
用法¶
runscript
命令可以在shell中调用 scripts 目录下的Python脚本.
例如:
$ python manage.py runscript delete_all_questions
提示: runscript
命令会首先检查每个app下的 scripts 目录,如果找到对应名字的脚本就会执行.然后检查 project_root/scripts 目录下是否包含符合名字的脚本,如果找到也会执行.也就是说,我们可以在不同的app中创建相同名字的脚本,并且都会被执行.
参数¶
--script-args
参数可以接收逗号分隔的值,并将其作为参数传递到方法内,例如
$ python manage.py runscript delete_all_questions --script-args staleonly
例子中 --script-args
参数值作为执行脚本的 run() 方法的参数传入,使用举例
# scripts/delete_all_questions.py
from datetime import timedelta
from django.utils import timezone
from polls.models import Question
def run(*args):
# Get all questions
questions = Question.objects.all()
if 'staleonly' in args:
# Only get questions more than 100 days old
questions = questions.filter(pub_date__lt=timezone.now() - timedelta(days=100))
# Delete questions
questions.delete()
调试¶
默认情况下, 代码抛出异常时不会显示错误堆栈. 如果想要跟踪错误堆栈,
需要添加 --traceback
参数. 例如
$ python manage.py runscript delete_all_questions --traceback
export_emails¶
概要: | 以不同的格式导出用户的邮件列表 |
---|
大部分Django站点包含注册用户的信息.有时我们需要将用户邮箱信息导入到其它系统中(生成邮件, Gmail, Google Docs, 修改权限, LinkedLn用户组等等). export_emails
命令为此而设计.导出的用户信息的同时可以对其进行分组.
用法举例¶
将所有用户信息导出成 '"First Last" <my@addr.com>;'
格式:
$ ./manage.py export_emails > addresses.txt
以LinkedIn pre-approve格式从 Attendees
组中导出用户信息:
$ ./manage.py export_emails -g Attendees -f linkedin pycon08.csv
以GMail(Google Docs)格式创建一个CSV文件:
$ ./manage.py export_emails --format=google google.csv
Model 字段扩展¶
概要: | 数据模型Model的字段扩展 |
---|
当前数据模型的字段的扩展¶
AutoSlugField
- 自动生成一个唯一的slug, 生成方式是以迭代方式给当前字段后面添加一个随机字符, 直到不重复为止.slug生成方式的灵感来自于 SmileyChris 的唯一码生成代码片段.RandomCharField
- 自动生成一个指定长度的全局唯一随即字符串. 默认包含数字并区分大小写. 长度为8时, 大约有340万种组合, 长度为12时, 大约有20亿中组合. 参考示例:>>> RandomCharField(length=8, unique=True) BVm9GEaE >>> RandomCharField(length=4, include_alpha=False) 7097 >>> RandomCharField(length=12, include_punctuation=True) k[ZS.TR,0LHO >>> RandomCharField(length=12, lowercase=True, include_digits=False) pzolbemetmok
CreationDateTimeField
- DateTimeField类型字段,会自动保存数据第一次被保存到数据库的时间戳.工作方式与添加了auto_now_add=True
参数相同,而auto_now_add
参数已经不推荐使用.ModificationDateTimeField
- DateTimeField类型字段,当数据出现修改是会自动保存被修改的时间戳.工作方式与添加了auto_now=True
参数相同. 保存时将update_modified参数设置为False则本次保存不会更新时间戳:>>> example = MyTimeStampedModel.objects.get(pk=1) >>> print example.modified datetime.datetime(2016, 3, 18, 10, 3, 39, 740349, tzinfo=<UTC>) >>> example.save(update_modified=False) >>> print example.modified datetime.datetime(2016, 3, 18, 10, 3, 39, 740349, tzinfo=<UTC>) >>> example.save() >>> print example.modified datetime.datetime(2016, 4, 8, 14, 25, 43, 123456, tzinfo=<UTC>)
也可以直接通过设置实例属性的方式, 禁止自动更新时间戳:
>>> example = MyCustomModel.objects.get(pk=1)
>>> print example.modified
datetime.datetime(2016, 3, 18, 10, 3, 39, 740349, tzinfo=<UTC>)
>>> example.update_modified=False
>>> example.save()
>>> print example.modified
datetime.datetime(2016, 3, 18, 10, 3, 39, 740349, tzinfo=<UTC>)
UUIDField
- 唯一标识码字段,通过当前系统的Python模块生成的唯一标识码.1.4.7 版后已移除: Django 1.8 开始支持原生UUIDField字段. Django-Extensions会支持这个字段直到 Django1.7不再维护.
PostgreSQLUUIDField
- uid字段, 使用了PostgreSQL的uuid类型.1.4.7 版后已移除: Django 1.8 开始支持原生UUIDField字段. Django-Extensions会支持这个字段直到 Django1.7不再维护.
EncryptedCharField
- 字符串类型字段,会将数据以加密的方式保存和现实,加密方法使用 Keyczar.使用这个扩展字段时需要安装Keyczar,通过Keyczar库生成加密的密钥,还要在django项目的settings.py
中添加settings.ENCRYPTED_FIELD_KEYS_DIR
配置,指向密钥的完整目录.EncryptedTextField
- 字符串类型字段,与EncryptedCharField
字段类似,但是继承自TextField
字段.ShortUUIDField
- 字符串类型字段,将生成的uuid转换成较短的字符串(好像是57进制)。生成字符串结果的长度小于22位,通过参数可以生成更短的字符长度,短长度字符虽然不能保证绝对的唯一性,但重复的概率极低JSONField
- 基于TextField类型, 并支持JSON的序列化和反序列化. Django 1.9 引入了基于PostgreSQL的 JSONField, 但只能在使用PostgreSQL并且Django版本在1.9以上的用户才能使用.
graph_models¶
概要: | 将整个项目或指定app的models结果渲染成图形 [1]. |
---|
创建一个 GraphViz 格式文件,包含对于指定app的models的描述.可以传入多个app,这样就会把它们渲染到同一个文件中.输出结果通常是一个 .dot
后缀文件.
graph_model
命令可以通过些参数改变生成的图形,比如: 分组模型,包含继承,去除部分模型,改变模型中列的位置等.
新版本的 django-extensions
还可以直接渲染成一张图片,这个功能需要安装 pygraphviz 库.
选择生成图表的库¶
graph_model
命令可以指定使用哪个库来生成图片,使用参数 --pygraphviz
或 --pydot
,需要安装相应的依赖库.
默认选择 pygraphviz
库生成图表,如果没有指定参数,也没有安装 pygraphviz
库,则会抛出异常.
安装 pygraphviz
库:
$ pip install pygraphviz
安装是可能因为无法编译需要的C扩展而安装失败.那么可能需要尝试其它安装方法,或使用 PyDot
.
安装 pydot
库:
$ pip install pyparsing==1.5.7
$ pip install pydot
安装过程很快,注意要安装指定版本的 pyparsing
.否则可能会出错:
Couldn't import dot_parser, loading of dot files will not be possible.
默认配置¶
在项目的配置文件中可以使用 GRAPH_MODELS
配置生成图表时的默认参数:
GRAPH_MODELS = {
'all_applications': True,
'group_models': True,
}
配置的参数名与在命令行中的参数名是一样的,只要去掉作为参数的两个建号,并把参数中的减号换成下划线.
模板¶
Django的模板可以用来生成dot格式文件,通过 pygraphviz 或 pydot 可以把dot文件内容生成图片,这些模板文件是可以扩展和复写的。
使用的模板:
- django_extensions/graph_models/digraph.dot
- django_extensions/graph_models/label.dot
- django_extensions/graph_models/relation.dot
关于如何生成dot文件,可以参考: http://www.graphviz.org/Documentation.php
用例¶
安装 django-extensions
后,就可以创建 .dot
文件.或通过 graph_models
命令生成图表,看下面的例子:
# 创建一个 .dot 文件
$ ./manage.py graph_models -a > my_project.dot
# 创建一个PNG图片,包含应用的结构,把图片命名为my_project_visualized.png
$ ./manage.py graph_models -a -g -o my_project_visualized.png
# 这个例子中指明了使用哪个Python的图表库
$ ./manage.py graph_models --pygraphviz -a -g -o my_project_visualized.png
$ ./manage.py graph_models --pydot -a -g -o my_project_visualized.png
# 生成一个只包含 'foo' 和 'bar' 应用的 dot 文件
$ ./manage.py graph_models foo bar > my_project.dot
# 生成只包含某些模型的图片
$ ./manage.py graph_models -a -I Foo,Bar -o my_project_subsystem.png
# 生成不包含某些模型的图片
$ ./manage.py graph_models -a -X Foo,Bar -o my_project_sans_foo_bar.png
[1] | 渲染出的是图形的描述语言,需要用特定软件才能看到图形,如果用文本编辑器打开则会看到描述字符 |
定时任务¶
概要: | 在Django-extensions中使用定时任务. |
---|
定时的计划任务¶
本页介绍的功能正在努力改进中¶
新建一个与Django的命令执行方式类似的任务 [1].使用 create_jobs
命令在一个app内创建一个 ‘jobs’ 目录,然后可以创建不同的Python脚本执行不同的任务.
django_extensions.jobs
目录中包含了一些简单的例子.
Python的任务脚本继承定时任务类后就会被定义为任务,可以按小时,按天,按周或按月执行.继承的脚本必须实现 execute
方法,该方法在任务触发时会被自动执行.
与任务相关的命令还包括:
- create_jobs: 创建包含任务的目录
- runjob: 执行单独的任务
- runjobs: 执行所有任务
列出所有任务:
runjob[s] -l
未触发时,任务不会自己执行.
任务需要手动执行,或指定时间执行,或在 cron
中配置定期执行
@hourly /path/to/my/project/manage.py runjobs hourly
@daily /path/to/my/project/manage.py runjobs daily
@weekly /path/to/my/project/manage.py runjobs weekly
@monthly /path/to/my/project/manage.py runjobs monthly
[1] | 意味着可以想Django的shell命令那样引入项目中的app相关类和方法 |
数据库字段扩展¶
概要: | 数据字段的扩展 |
---|
数据库字段的扩展¶
TimeStampedModel
- 抽象类,包含了由自己管理的created
和modified
字段.TitleDescriptionModel
- 虚拟类, 包含了title和description两个字段.TitleSlugDescriptionModel
- 虚拟类, 包含了title和description两个字段. 并具有自动管理 slug 字段的功能. slug字段生成字title字段.
命名空间的建议¶
概要: | 命名空间的建议 |
---|
简介¶
请使用 django_extensions
的命名空间,而不是绝对路径
命名空间的建议¶
一些简单的建议:
- django_extensions.commands (20% 的人在正式环境中使用的绝对路径)
- django_extensions.commands.development (所有在开发中都会用到的功能)
- django_extensions.commands.extra
- django_extensions.db
- django_extensions.templates
- django_extensions.jobs
数据库部分使用方式都是正确的,因为目前只有一种引用方式:
from django_extensions.db.models import something
print_settings¶
概要: | print_settings 命令与Django的 diffsettings 命令相似,但是会输出当前项目中使用的全部配置(包括默认配置) |
---|
简介¶
Django使用 diffsettings
命令输出当前项目配置与默认配置的区别.有时也需要直接查看当前项目的所有配置,尤其是配置十分复杂的时候,比如都包含好几个配置文件 [1].例如,在测试和开发环境中使用不同的配置文件,并且都包含了默认的 settings.py
文件,这样就不能直观的查看配置文件了.
print_settings
命令支持从不同的格式文件中输出数据.
详情¶
最简单的输出配置命令如下,不需要添加参数:
$ python manage.py print_settings
以不同格式输出
$ python manage.py print_settings --format=json
$ python manage.py print_settings --format=yaml # 需要安装 PyYAML
$ python manage.py print_settings --format=pprint
$ python manage.py print_settings --format=text
$ python manage.py print_settings --format=value
只显示指定参数
$ python manage.py print_settings DEBUG INSTALLED_APPS
$ python manage.py print_settings DEBUG INSTALLED_APPS --format=pprint
$ python manage.py print_settings INSTALLED_APPS --format=value
通过 --help
参数可以获取更多帮助:
$ python manage.py print_settings --help
Usage: manage.py print_settings [options]
Print the active Django settings.
Options:
-v VERBOSITY, --verbosity=VERBOSITY
Verbosity level; 0=minimal output, 1=normal output,
2=verbose output, 3=very verbose output
--settings=SETTINGS The Python path to a settings module, e.g.
"myproject.settings.main". If this isn't provided, the
DJANGO_SETTINGS_MODULE environment variable will be
used.
--pythonpath=PYTHONPATH
A directory to add to the Python path, e.g.
"/home/djangoprojects/myproject".
--traceback Print traceback on exception
--format=FORMAT Specifies output format.
--indent=INDENT Specifies indent level for JSON and YAML
--version show program's version number and exit
-h, --help show this help message and exit
[1] | django1.4版本后推荐配置文件全部都放在项目的 主app 内,到了1.6版本更进一步简化了配置文件包含的内容.但很多项目开发者会自己定义多个配置文件,以便用在不同的环境下 |
runprofileserver¶
首先,在跟踪分析一门语言和框架前,应该深入了解一下正在使用的语言(框架),这样才能事半功倍.不够扎实的功底会导致在跟踪分析服务时做出错误的假设和判断.有一条经验法则很实用:干净整洁的代码比热情和耐心更实用.
这部分功能正在持续改进中,如果你有好的办法能够跟踪,分析Django框架,请给我们留言
简介¶
runprofileserver
命令在启动django服务的同时其用了跟踪分析工具,会将服务的分析信息保存到 .prof
后缀文件中.使用 --prof-path
参数指定保存分析文件到指定目录.每一个请求的分析数据都会被保存成一个profile文件.
如果没有指定 --prof-path
参数,分析数据的 .prof
文件会被保存到 /tmp
目录下.建议使用特定目录保存分析文件,这样方便我们随时查看分析数据,也不会弄乱 /tmp
目录,使用windows系统时一定要指定``–prof-path`` 参数,因为windows系统没有 /tmp
目录.
分析文件的名字默认名字是:
{path}.{duration:06d}ms.{time}
也可以通过 --prof-file
参数指定生成的服务分析文件名字.文件名格式规则参考: Format Specification.
例如:
- “{time}-{path}-{duration}ms” - 用请求的道达时间命名分析文件.
- “{duration:06d}ms.{path}.{time}” - 用请求的相应时间命名分析文件.
聚合profile¶
Django提供了一个profile文件聚合的工具 gather_profile_stats.py
,在Django安装目录的 bin
目录下可以找到.
Profiler选择¶
runprofileserver
支持两种 profilers : hotshot 和 cProfile. 两个都是Python标准库. cProfile 比较新, 而且可能不支持所有系统. 所以默认的 profiler 是*hotshot*.
但是 hotshot 已经不再维护了. <https://docs.python.org/2/library/profile.html#introduction-to-the-profilers>`_
cProfile 通常是一个更好的选择. 通过 --use-cprofile
参数来检测当前系统是否支持 cProfile;
例子:
$ mkdir /tmp/my-profile-data
$ ./manage.py runprofileserver --use-cprofile --prof-path=/tmp/my-profile-data
如果使用默认profiler后, pstats
模块和 GUI 工具都打不开记录, 并且提示 “ValueError: bad marshal data (unknown type code)”. 尝试使用*cProfile*作为profiler来解决问题.
KCacheGrind¶
新版本的 runprofileserver
命令可以把分析的结果文件保存成 KCacheGrind 格式文件,这样就可以通过 KCacheGrind 的分析工具来查看分析数据.
例子:
$ mkdir /tmp/my-profile-data
$ ./manage.py runprofileserver --kcachegrind --prof-path=/tmp/my-profile-data
Validating models...
0 errors found
Django version X.Y.Z, using settings 'complete_project.settings'
Development server is running at http://127.0.0.1:8000/
Quit the server with CONTROL-C.
[13/Nov/2008 06:29:38] "GET / HTTP/1.1" 200 41107
[13/Nov/2008 06:29:39] "GET /site_media/base.css?743 HTTP/1.1" 200 17227
[13/Nov/2008 06:29:39] "GET /site_media/logo.png HTTP/1.1" 200 3474
[13/Nov/2008 06:29:39] "GET /site_media/jquery.js HTTP/1.1" 200 31033
[13/Nov/2008 06:29:39] "GET /site_media/heading.png HTTP/1.1" 200 247
[13/Nov/2008 06:29:39] "GET /site_media/base.js HTTP/1.1" 200 751
<ctrl-c>
$ kcachegrind /tmp/my-profile-data/root.12574391.592.prof
相关知识链接¶
- http://code.djangoproject.com/wiki/ProfilingDjango
- http://www.rkblog.rk.edu.pl/w/p/django-profiling-hotshot-and-kcachegrind/
- http://code.djangoproject.com/browser/django/trunk/django/bin/profiling/gather_profile_stats.py
- http://www.oluyede.org/blog/2007/03/07/profiling-django/
- http://simonwillison.net/2008/May/22/debugging/
runserver_plus¶
概要: | runserver_plus 命令启动测试服务,并用 Werkzeug 作为调试后台,这个命令是对原生命令 runserver 的扩展,提供了更强的错误调试功能. |
---|
简介¶
runserver_plus
命令需要安装 Werkzeug WSGI utilities . Werkzeug
是Python作为web服务的杀手级调试工具,还能进行基于ajax的错误断点调试(允许在出错的地方执行代码). 当然还提供了一个漂亮的错误展示页面.
开始使用¶
在启动Django的测试服务时,只要用 runserver_plus
命令代替 runserver
命令就可以了:
$ python manage.py runserver_plus
* Running on http://127.0.0.1:8000/
* Restarting with reloader...
Validating models...
0 errors found
Django version X.Y.Z, using settings 'screencasts.settings'
Development server is running at http://127.0.0.1:8000/
Using the Werkzeug debugger (http://werkzeug.pocoo.org/)
Quit the server with CONTROL-C.
runserver_plus
命令接受原来的所有参数.也就是可以随意指定端口和host,跟原生的 runserver
命令一模一样.
深入使用¶
runserver_plus
启动的服务遇到代码抛出异常时,会得到一个 Werkzeug 的错误显示页面(不是默认的Django错误页面).

当鼠标划过特定错误行(堆栈)时,就会显示出当前位置的调试扩展功能,注意图片右边出现的2个按钮:

这2个选项是:
查看源码¶
这是点击 显示源码 后的效果:

产看错误产生的源码有助于快速定位错误原因.抛出异常的部分被高亮显示,这样更方便查看.
有一个不够人性化的地方是,点击 查看源码 后,页面没有自动滚动到底部(源码显示的地方),这容易让人觉得什么都没有发生,其实是没有看到.
命令行调试¶
在错误页面上点击命令行调试按钮后,会显示出一个命令行调试工具(网页里面的输入框),是不是屌爆了:

这样就会出现一个基于ajax的命令行调试工具,输入的命令通过ajax方式发送到后台,再把返回的结果输出,然后就可以任意发挥了.截图中,在调试框里输入了 print environ
命令来查看当前环境中给方法传入了哪些参数.
注意 : 该方法不能被用在任何正式环境中,即使是在正式环境中检测问题时也不行.命令行调试工具允许在服务器端执行Python命令,这是非常危险的.
SSL¶
runserver_plus
还支持SSL,这样就可以方便的调试 https
请求了.使用SSL时需要提供证书的名字, runserver_plus
会自动生成一个证书:
$ python manage.py runserver_plus --cert cert
Validating models...
0 errors found
Django version X.Y.Z, using settings 'mysite.settings'
Development server is running at http://127.0.0.1:8000/
Using the Werkzeug debugger (http://werkzeug.pocoo.org/)
Quit the server with CONTROL-C.
* Running on https://127.0.0.1:8000/
* Restarting with reloader
Validating models...
0 errors found
Django version X.Y.Z, using settings 'mysite.settings'
Development server is running at http://127.0.0.1:8000/
Using the Werkzeug debugger (http://werkzeug.pocoo.org/)
Quit the server with CONTROL-C.
执行上面的命令后就可以通过 https://127.0.0.1:8000
在安全模式下访问服务了.在项目目录下会创建2个新的文件,分别是密钥文件和证书文件.重启测试服务时,这2个文件会被保留下来,这样浏览器就不用反复处理证书授权了.如果想使用指定证书文件,可以使用路径参数指向该证书文件:
$ python manage.py runserver_plus --cert /tmp/cert
使用SSL时需要安装 OpenSSL
库. Werkzeug
0.9版本后才允许重用证书文件.通过以下命令安装 OpenSSL
库:
$ pip install pyOpenSSL
配置¶
设置 RUNSERVERPLUS_SERVER_ADDRESS_PORT 来跳转开发环境中使用的地址和端口
如果可以通过以下命令启动服务:
$ python manage.py runserver_plus 0.0.0.0:8000
那么就可以设置开发时使用的默认地址和端口:
RUNSERVERPLUS_SERVER_ADDRESS_PORT = '0.0.0.0:8000'
添加设置, 使Werkzeug在console中输出log:
LOGGING = {
...
'handlers': {
...
'console': {
'level': 'DEBUG',
'class': 'logging.StreamHandler',
},
},
'loggers': {
...
'werkzeug': {
'handlers': ['console'],
'level': 'DEBUG',
'propagate': True,
},
},
}
CPU及IO的用量¶
这个问题 gh625 导致 runserver_plus 在系统空闲时会占用很多系统资源. 这是因为 Werkzeug 包含了一个自动重新加载的功能. 通过 stat polling 和 file system events 两种方式来实现自动重新加载.
stat polling 这种自动重新加载的方式十分简单粗暴. 导致的问题是系统资源占用率高.
安装 Watchdog 包后, 它会不断尝试使用 file system events 方式, 能使用就自动使用.
更多内容参考 Werkzeug 文档
通过两种方式来设置自动重新加载的参数, Django配置文件:
RUNSERVERPLUS_POLLER_RELOADER_INTERVAL = 5
或者通过命令行参数”
$ python manage.py runserver_plus –reloader-interval 5
调试 (Debugger PIN)¶
摘要:
下面有关调试的说明来自 Werkzeug_ 的文档
-- http://werkzeug.pocoo.org/docs/0.11/debug/#debugger-pin
Werkzeug 0.11 开始调试工具受到PIN的保护. 这种方式能模拟生产环境, 真实的用户使用的情景下调试. PIN默认开启认证功能.
调试器启动时, 首先会在命令行里输出PIN, 这个PIN是通过安全方式生成的并针对当前项目的. 由环境变量 WERKZEUG_DEBUG_PIN 生成的PIN, 遇到服务重启的时候很难达到安全模式. This can be set to a number and will become the PIN. This variable can also be set to the value off to disable the PIN check entirely.
如果执行了多次错误的PIN的插入方式, 那么就需要重启当前服务了.
这个功能不是为了鼓励线上调试的. 而是为了避免攻击者利用线上调试功能. 在生产环境中, 永远不要开启调试功能.
sync_s3¶
概要: | 将项目的 MEDIA_ROOT 和 STATIC_ROOT 目录包含的文件同步到S3 [1]. |
---|
sync_s3
命令会检索配置中的 settings.MEDIA_ROOT
目录和 settings.STATIC_ROOT
目录,然后把所有文件资源上传到S3的相同的目录结构下.
sync_s3
命令可以启用以下功能,通过传入参数启用对应功能,默认全部关闭:
* gzip 压缩CSS和JS文件,并添加 ``Content-Encoding`` 头.
* 设置文件缓存过期时间
* 只上传 media 或 static 目录文件.
* 使用其它的S3同步工具
* 设置public文件的访问控制列表
用法举例¶
上传到S3的 mybucket
$ ./manage.py sync_s3 mybucket
上传到S3的 mybucket ,并对CSS/JS文件进行gzip压缩和添加缓存过期时间:
$ ./manage.py sync_s3 mybucket --gzip --expires
只上传 media 文件到S3的 mybucket 中
$ ./manage.py sync_s3 mybucket --media-only # or --static-only
# Upload only media files to a S3 compatible provider into the bucket 'mybucket' and set private file ACLs
$ ./manage.py sync_s3 mybucket --media-only --s3host=cs.example.com --acl=private
依赖的库和配置¶
sync_s3
命令需要安装 boto
库,改命令在1.4c版本下测试通过:
当然还要添加AWS账户的S3密钥和bucket名称,在项目配置文件 settings.py
文件中增加配置:
# settings.py
AWS_ACCESS_KEY_ID = ''
AWS_SECRET_ACCESS_KEY = ''
AWS_BUCKET_NAME = 'bucket'
可选配置¶
可以在 settings.py
文件种设置好全部的 sync_s3
的参数,实现自动上传
# settings.py
AWS_S3_HOST = 'cs.example.com'
AWS_DEFAULT_ACL = 'private'
SYNC_S3_PREFIX = 'some_prefix'
FILTER_LIST = 'dir1, dir2'
AWS_CLOUDFRONT_DISTRIBUTION = 'E27LVI50CSW06W'
SYNC_S3_RENAME_GZIP_EXT = '.gz'
[1] | S3是亚马逊提供的云存储服务,也是目前行业中使用最广泛的云存储服务.2013年底亚马逊云服务才宣布正式入华,估计2014年中旬才能用上. |
sqldiff¶
概要: | sqldiff 命令会检测指定app与数据库表之间的差别,并输出数据库表的修改语句. |
---|
sqldiff
命令不是用来合并数据库差别的工具,虽然能够查看区别,但这个命令的设计初衷只是检查数据库表结构与django数据模型的区别.
用法举例¶
查看所有app数据模型与数据库之间的区别:
$ ./manage.py sqldiff -a
用文本显示所有app数据模型与数据库之间的区别:
$ ./manage.py sqldiff -a -t
sqlcreate¶
概要: | sqlcreate 命令可以更方便的创建数据库. |
---|
简介¶
不用再手动创建数据库, settings.py
文件中已经包含了需要的信息,所以Do It Yourself.
用法¶
$ python manage.py sqlcreate [--router=<routername>] | <my_database_shell_command>
sqlcreate
命令会将SQL语句输出用来检查(如果你想检查的话).但最终还是要输入到数据库的shell中来执行.
如果有合适的方法证明当前用户有修改数据库的权限,那就可以把输出结果直接导入到数据库中.但是因为项目的配置方式,这种直接修改数据库的方式是不能接受的.
sqldsn¶
概要: | 在标准输出中打印数据资源的名称和关系. |
---|
退出状态码¶
退出状态码始终是 0
用法举例¶
# 打印默认数据库资源名称
$ ./manage.py sqldsn
# 打印所有数据库资源名称
$ ./manage.py sqldsn --all
# 打印 'slave' 数据库的资源名称
$ ./manage.py sqldsn --router=slave
# 打印默认数据库所有可用资源
$ ./manage.py sqldsn --style=all
# 使用 quite(安静) 模式, 通过默认数据库生成 .pgpass 文件
$ ./manage.py sqldsn -q --style=pgpass > .pgpass
validate_templates¶
概要: | 检查模板的语法错误或编译错误. |
---|
参数¶
verbosity¶
该参数表示使用高级输出错误信息详细级别,会将所有检查过的模板的错误全部输出.否则只会输出最近的查找到错误的文件信息.
break¶
遇到错误就直接输出不再继续检查
includes¶
通过参数 -i
(可以重复使用)来添加自定义的模板目录
配置¶
VALIDATE_TEMPLATES_EXTRA_TEMPLATE_DIRS¶
通过 VALIDATE_TEMPLATES_EXTRA_TEMPLATE_DIRS
配置可以指定所有模板目录的前缀.
这个配置主要针对 TEMPLATE DIRS
是动态的或模板目录是通过中间件生成的情况.
扩展app的模板,比如Django项目中若是包含的 celery
模块
也可以通过指定该参数来进行模板语法检测.
用法举例¶
./manage.py validate_templates
[1] | Django的单个版本指定了需要的Python版本,支持某个Django版本就代表同时支持相应的Python版本. |