django “如何”系列2:如何编写django-admin 命令
应用可以使用manage.py注册自己的动作,例如,你可能想要为你即将发布的应用添加一个manage.py 操作。这节我们将为polls应用添加一个closepoll的命令
添加一个management/commands目录如下
polls/
__init__.py
models.py
management/
__init__.py
commands/
__init__.py
_private.py
closepoll.py
tests.py
views.py
这样添加之后,任何包含polls在INSTALLED_APPS的项目都可以使用closepoll命令
_private.py模块不会作为一个管理命令
closepoll.py模块有一个要求--必须定义一个类Command拓展或者继承BaseCommand
下面是这个命令的一个实例实现(closepoll.py)
from django.core.management.base import BaseCommand, CommandError
from example.polls.models import Poll class Command(BaseCommand):
args = '<poll_id poll_id ...>'
help = 'Closes the specified poll for voting' def handle(self, *args, **options):
for poll_id in args:
try:
poll = Poll.objects.get(pk=int(poll_id))
except Poll.DoesNotExist:
raise CommandError('Poll "%s" does not exist' % poll_id) poll.opened = False
poll.save() self.stdout.write('Successfully closed poll "%s"\n' % poll_id)
注意:使用self.stdout和self.stderr而不是stdout和stderr
这个新命令的可以通过python manage.py closepoll <poll_id>来调用
更多更详细的关于BaseCommand的代码附于下面:常用到的参数是args(参数格式说明)和help(命令说明),必须实现的方法是handle(如何实现这个命令),正如上面的例子的那样,如果没有特别的要求,下面的代码其实不用看了。
class BaseCommand(object):
"""
The base class from which all management commands ultimately
derive. Use this class if you want access to all of the mechanisms which
parse the command-line arguments and work out what code to call in
response; if you don't need to change any of that behavior,
consider using one of the subclasses defined in this file. If you are interested in overriding/customizing various aspects of
the command-parsing and -execution behavior, the normal flow works
as follows: 1. ``django-admin.py`` or ``manage.py`` loads the command class
and calls its ``run_from_argv()`` method. 2. The ``run_from_argv()`` method calls ``create_parser()`` to get
an ``OptionParser`` for the arguments, parses them, performs
any environment changes requested by options like
``pythonpath``, and then calls the ``execute()`` method,
passing the parsed arguments. 3. The ``execute()`` method attempts to carry out the command by
calling the ``handle()`` method with the parsed arguments; any
output produced by ``handle()`` will be printed to standard
output and, if the command is intended to produce a block of
SQL statements, will be wrapped in ``BEGIN`` and ``COMMIT``. 4. If ``handle()`` raised a ``CommandError``, ``execute()`` will
instead print an error message to ``stderr``. Thus, the ``handle()`` method is typically the starting point for
subclasses; many built-in commands and command types either place
all of their logic in ``handle()``, or perform some additional
parsing work in ``handle()`` and then delegate from it to more
specialized methods as needed. Several attributes affect behavior at various steps along the way: ``args``
A string listing the arguments accepted by the command,
suitable for use in help messages; e.g., a command which takes
a list of application names might set this to '<appname
appname ...>'. ``can_import_settings``
A boolean indicating whether the command needs to be able to
import Django settings; if ``True``, ``execute()`` will verify
that this is possible before proceeding. Default value is
``True``. ``help``
A short description of the command, which will be printed in
help messages. ``option_list``
This is the list of ``optparse`` options which will be fed
into the command's ``OptionParser`` for parsing arguments. ``output_transaction``
A boolean indicating whether the command outputs SQL
statements; if ``True``, the output will automatically be
wrapped with ``BEGIN;`` and ``COMMIT;``. Default value is
``False``. ``requires_model_validation``
A boolean; if ``True``, validation of installed models will be
performed prior to executing the command. Default value is
``True``. To validate an individual application's models
rather than all applications' models, call
``self.validate(app)`` from ``handle()``, where ``app`` is the
application's Python module. """
# Metadata about this command.
option_list = (
make_option('-v', '--verbosity', action='store', dest='verbosity', default='',
type='choice', choices=['', '', '', ''],
help='Verbosity level; 0=minimal output, 1=normal output, 2=verbose output, 3=very verbose output'),
make_option('--settings',
help='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.'),
make_option('--pythonpath',
help='A directory to add to the Python path, e.g. "/home/djangoprojects/myproject".'),
make_option('--traceback', action='store_true',
help='Print traceback on exception'),
)
help = ''
args = '' # Configuration shortcuts that alter various logic.
can_import_settings = True
requires_model_validation = True
output_transaction = False # Whether to wrap the output in a "BEGIN; COMMIT;" def __init__(self):
self.style = color_style() def get_version(self):
"""
Return the Django version, which should be correct for all
built-in Django commands. User-supplied commands should
override this method. """
return django.get_version() def usage(self, subcommand):
"""
Return a brief description of how to use this command, by
default from the attribute ``self.help``. """
usage = '%%prog %s [options] %s' % (subcommand, self.args)
if self.help:
return '%s\n\n%s' % (usage, self.help)
else:
return usage def create_parser(self, prog_name, subcommand):
"""
Create and return the ``OptionParser`` which will be used to
parse the arguments to this command. """
return OptionParser(prog=prog_name,
usage=self.usage(subcommand),
version=self.get_version(),
option_list=self.option_list) def print_help(self, prog_name, subcommand):
"""
Print the help message for this command, derived from
``self.usage()``. """
parser = self.create_parser(prog_name, subcommand)
parser.print_help() def run_from_argv(self, argv):
"""
Set up any environment changes requested (e.g., Python path
and Django settings), then run this command. """
parser = self.create_parser(argv[0], argv[1])
options, args = parser.parse_args(argv[2:])
handle_default_options(options)
self.execute(*args, **options.__dict__) def execute(self, *args, **options):
"""
Try to execute this command, performing model validation if
needed (as controlled by the attribute
``self.requires_model_validation``). If the command raises a
``CommandError``, intercept it and print it sensibly to
stderr.
"""
show_traceback = options.get('traceback', False) # Switch to English, because django-admin.py creates database content
# like permissions, and those shouldn't contain any translations.
# But only do this if we can assume we have a working settings file,
# because django.utils.translation requires settings.
saved_lang = None
if self.can_import_settings:
try:
from django.utils import translation
saved_lang = translation.get_language()
translation.activate('en-us')
except ImportError, e:
# If settings should be available, but aren't,
# raise the error and quit.
if show_traceback:
traceback.print_exc()
else:
sys.stderr.write(smart_str(self.style.ERROR('Error: %s\n' % e)))
sys.exit(1) try:
self.stdout = options.get('stdout', sys.stdout)
self.stderr = options.get('stderr', sys.stderr)
if self.requires_model_validation:
self.validate()
output = self.handle(*args, **options)
if output:
if self.output_transaction:
# This needs to be imported here, because it relies on
# settings.
from django.db import connections, DEFAULT_DB_ALIAS
connection = connections[options.get('database', DEFAULT_DB_ALIAS)]
if connection.ops.start_transaction_sql():
self.stdout.write(self.style.SQL_KEYWORD(connection.ops.start_transaction_sql()) + '\n')
self.stdout.write(output)
if self.output_transaction:
self.stdout.write('\n' + self.style.SQL_KEYWORD("COMMIT;") + '\n')
except CommandError, e:
if show_traceback:
traceback.print_exc()
else:
self.stderr.write(smart_str(self.style.ERROR('Error: %s\n' % e)))
sys.exit(1)
if saved_lang is not None:
translation.activate(saved_lang) def validate(self, app=None, display_num_errors=False):
"""
Validates the given app, raising CommandError for any errors. If app is None, then this will validate all installed apps. """
from django.core.management.validation import get_validation_errors
try:
from cStringIO import StringIO
except ImportError:
from StringIO import StringIO
s = StringIO()
num_errors = get_validation_errors(s, app)
if num_errors:
s.seek(0)
error_text = s.read()
raise CommandError("One or more models did not validate:\n%s" % error_text)
if display_num_errors:
self.stdout.write("%s error%s found\n" % (num_errors, num_errors != 1 and 's' or '')) def handle(self, *args, **options):
"""
The actual logic of the command. Subclasses must implement
this method. """
raise NotImplementedError()
BaseCommand
django “如何”系列2:如何编写django-admin 命令的更多相关文章
- Django学习系列4:编写第一个简单的应用代码
首页视图编写 lists/tests.py from django.test import TestCasefrom django.urls import resolvefrom lists.view ...
- django “如何”系列4:如何编写自定义模板标签和过滤器
django的模板系统自带了一系列的内建标签和过滤器,一般情况下可以满足你的要求,如果觉得需更精准的模板标签或者过滤器,你可以自己编写模板标签和过滤器,然后使用{% load %}标签使用他们. 代码 ...
- django “如何”系列3:如何编写模型域(model filed)
django自带很多的域类--CharField,DateField等等--,如果django的这些域都不能满足你精确的要求,那么你可以编写自己的模型域. django自带的域没有和数据库列类型一一对 ...
- Django学习系列5:为视图编写单元测试
打开lists/tests.py编写 """向浏览器返回真正的HTML响应,添加一个新的测试方法""" from django.test i ...
- django “如何”系列5:如何编写自定义存储系统
如果你需要提供一个自定义的文件存储-一个常见的例子便是在远程系统上存储文件-你可以通过定义一个自己的存储类来做这件事情,你将通过一下步骤: 你自定义的存储系统一定是django.core.files. ...
- Python+Django+SAE系列教程17-----authauth (认证与授权)系统1
通过session,我们能够在多次浏览器请求中保持数据,接下来的部分就是用session来处理用户登录了. 当然,不能仅凭用户的一面之词,我们就相信,所以我们须要认证. 当然了,Django 也提供了 ...
- Django App(二) Connect Mysql & defualt App admin
这一篇接着上一篇polls App自动创建admin app. 1.安装数据库 这里的内容从官网看越看越像 EntityFramework的内容.Python支持SQLite,MySql,Or ...
- Django实现自定义template页面并在admin site的app模块中加入自定义跳转链接
在文章 Django实现自定义template页面并在admin site的app模块中加入自定义跳转链接(一) 中我们成功的为/feedback/feedback_stats/路径自定义了使用tem ...
- Django之静态文件,中间件,admin后台管理
静态文件 静态文件的使用 在 网页使用的css文件,js文件和图片等叫做静态文件.1)在项目下新建静态文件夹 static. 2) 配置静态文件所在的物理目录.Settings.py STATIC_U ...
- Django学习系列7:使用模板解决“不测试常量”规则,使用模板重构
之前写的lists/tests.py中的单元测试,要查找特定的HTML字符串,但这不是测试HTML的高效方法. 单元测试规则之一“不测试常量”,编写断言检测HTML字符串中是否有制定的字符串序列,不是 ...
随机推荐
- BZOJ1101 & 洛谷3455:[POI2007]ZAP——题解
https://www.luogu.org/problemnew/show/3455#sub http://www.lydsy.com/JudgeOnline/problem.php?id=1101 ...
- [LOJ10186]任务安排
link 试题分析 一道斜率优化的dp 易得方程$f[j]=(S+t[i])\times c[j]+f[i]-t[i]\times c[i]+s\times c[n]$,为什么要写成这要,因为这样其实 ...
- stout代码分析之五:UUID类
UUID全称通用唯一识别码,被广泛应用于分布式系统中,让所有的元素具有唯一的标识. stout中UUID类继承自boost::uuids::uuid.api如下: random, 产生一个UUID对象 ...
- SQL Server2000安装教程图解
sql2000安装教程图解... ================================= 第一部分:下载所需要的安装包: 可以自己在网上百度了之后下载--或是直接从我已打包好的群里下载 = ...
- telnet退出
windows下退出telnet:可以参考下面linux退出,也可以直接关闭窗口. linux退出telnet: 1.输入ctrl+]:显示出telnet>. 2.此时可以输入?,查看可以使用的 ...
- tcp/ip 学习-通过视频学习
视频下载地址:http://down.51cto.com/zt/5518/ http://www.icoolxue.com/album/show/328 每天可以拿两个番茄钟看视频,主要目的还是了解, ...
- 洛谷 3029 [USACO11NOV]牛的阵容Cow Lineup
https://www.luogu.org/problem/show?pid=3029 题目描述 Farmer John has hired a professional photographer t ...
- 【C++对象模型】第五章 构造、解构、拷贝 语意学
1.构造语义学 C++的构造函数可能内带大量的隐藏码,因为编译器会扩充每一个构造函数,扩充程度视 class 的继承体系而定.一般而言编译器所做的扩充操作大约如下: 所有虚基类成员构造函数必须被调用, ...
- 【BZOJ1038】【ZJOI2008】瞭望塔 [模拟退火]
瞭望塔 Time Limit: 10 Sec Memory Limit: 162 MB[Submit][Status][Discuss] Description 致力于建设全国示范和谐小村庄的H村村 ...
- End to End Sequence Labeling via Bidirectional LSTM-CNNs-CRF论文小结
本篇论文是卡内基梅隆大学语言技术研究所2016年 arXiv:1603.01354v5 [cs.LG] 29 May 2016 今天先理解一下这个是什么意思: 找到的相关理解:arXi ...