应用可以使用manage.py注册自己的动作,例如,你可能想要为你即将发布的应用添加一个manage.py 操作。这节我们将为polls应用添加一个closepoll的命令

添加一个management/commands目录如下

  1. polls/
  2. __init__.py
  3. models.py
  4. management/
  5. __init__.py
  6. commands/
  7. __init__.py
  8. _private.py
  9. closepoll.py
  10. tests.py
  11. views.py

这样添加之后,任何包含polls在INSTALLED_APPS的项目都可以使用closepoll命令

_private.py模块不会作为一个管理命令

closepoll.py模块有一个要求--必须定义一个类Command拓展或者继承BaseCommand

下面是这个命令的一个实例实现(closepoll.py)

  1. from django.core.management.base import BaseCommand, CommandError
  2. from example.polls.models import Poll
  3.  
  4. class Command(BaseCommand):
  5. args = '<poll_id poll_id ...>'
  6. help = 'Closes the specified poll for voting'
  7.  
  8. def handle(self, *args, **options):
  9. for poll_id in args:
  10. try:
  11. poll = Poll.objects.get(pk=int(poll_id))
  12. except Poll.DoesNotExist:
  13. raise CommandError('Poll "%s" does not exist' % poll_id)
  14.  
  15. poll.opened = False
  16. poll.save()
  17.  
  18. 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(如何实现这个命令),正如上面的例子的那样,如果没有特别的要求,下面的代码其实不用看了。

  1. class BaseCommand(object):
  2. """
  3. The base class from which all management commands ultimately
  4. derive.
  5.  
  6. Use this class if you want access to all of the mechanisms which
  7. parse the command-line arguments and work out what code to call in
  8. response; if you don't need to change any of that behavior,
  9. consider using one of the subclasses defined in this file.
  10.  
  11. If you are interested in overriding/customizing various aspects of
  12. the command-parsing and -execution behavior, the normal flow works
  13. as follows:
  14.  
  15. 1. ``django-admin.py`` or ``manage.py`` loads the command class
  16. and calls its ``run_from_argv()`` method.
  17.  
  18. 2. The ``run_from_argv()`` method calls ``create_parser()`` to get
  19. an ``OptionParser`` for the arguments, parses them, performs
  20. any environment changes requested by options like
  21. ``pythonpath``, and then calls the ``execute()`` method,
  22. passing the parsed arguments.
  23.  
  24. 3. The ``execute()`` method attempts to carry out the command by
  25. calling the ``handle()`` method with the parsed arguments; any
  26. output produced by ``handle()`` will be printed to standard
  27. output and, if the command is intended to produce a block of
  28. SQL statements, will be wrapped in ``BEGIN`` and ``COMMIT``.
  29.  
  30. 4. If ``handle()`` raised a ``CommandError``, ``execute()`` will
  31. instead print an error message to ``stderr``.
  32.  
  33. Thus, the ``handle()`` method is typically the starting point for
  34. subclasses; many built-in commands and command types either place
  35. all of their logic in ``handle()``, or perform some additional
  36. parsing work in ``handle()`` and then delegate from it to more
  37. specialized methods as needed.
  38.  
  39. Several attributes affect behavior at various steps along the way:
  40.  
  41. ``args``
  42. A string listing the arguments accepted by the command,
  43. suitable for use in help messages; e.g., a command which takes
  44. a list of application names might set this to '<appname
  45. appname ...>'.
  46.  
  47. ``can_import_settings``
  48. A boolean indicating whether the command needs to be able to
  49. import Django settings; if ``True``, ``execute()`` will verify
  50. that this is possible before proceeding. Default value is
  51. ``True``.
  52.  
  53. ``help``
  54. A short description of the command, which will be printed in
  55. help messages.
  56.  
  57. ``option_list``
  58. This is the list of ``optparse`` options which will be fed
  59. into the command's ``OptionParser`` for parsing arguments.
  60.  
  61. ``output_transaction``
  62. A boolean indicating whether the command outputs SQL
  63. statements; if ``True``, the output will automatically be
  64. wrapped with ``BEGIN;`` and ``COMMIT;``. Default value is
  65. ``False``.
  66.  
  67. ``requires_model_validation``
  68. A boolean; if ``True``, validation of installed models will be
  69. performed prior to executing the command. Default value is
  70. ``True``. To validate an individual application's models
  71. rather than all applications' models, call
  72. ``self.validate(app)`` from ``handle()``, where ``app`` is the
  73. application's Python module.
  74.  
  75. """
  76. # Metadata about this command.
  77. option_list = (
  78. make_option('-v', '--verbosity', action='store', dest='verbosity', default='',
  79. type='choice', choices=['', '', '', ''],
  80. help='Verbosity level; 0=minimal output, 1=normal output, 2=verbose output, 3=very verbose output'),
  81. make_option('--settings',
  82. 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.'),
  83. make_option('--pythonpath',
  84. help='A directory to add to the Python path, e.g. "/home/djangoprojects/myproject".'),
  85. make_option('--traceback', action='store_true',
  86. help='Print traceback on exception'),
  87. )
  88. help = ''
  89. args = ''
  90.  
  91. # Configuration shortcuts that alter various logic.
  92. can_import_settings = True
  93. requires_model_validation = True
  94. output_transaction = False # Whether to wrap the output in a "BEGIN; COMMIT;"
  95.  
  96. def __init__(self):
  97. self.style = color_style()
  98.  
  99. def get_version(self):
  100. """
  101. Return the Django version, which should be correct for all
  102. built-in Django commands. User-supplied commands should
  103. override this method.
  104.  
  105. """
  106. return django.get_version()
  107.  
  108. def usage(self, subcommand):
  109. """
  110. Return a brief description of how to use this command, by
  111. default from the attribute ``self.help``.
  112.  
  113. """
  114. usage = '%%prog %s [options] %s' % (subcommand, self.args)
  115. if self.help:
  116. return '%s\n\n%s' % (usage, self.help)
  117. else:
  118. return usage
  119.  
  120. def create_parser(self, prog_name, subcommand):
  121. """
  122. Create and return the ``OptionParser`` which will be used to
  123. parse the arguments to this command.
  124.  
  125. """
  126. return OptionParser(prog=prog_name,
  127. usage=self.usage(subcommand),
  128. version=self.get_version(),
  129. option_list=self.option_list)
  130.  
  131. def print_help(self, prog_name, subcommand):
  132. """
  133. Print the help message for this command, derived from
  134. ``self.usage()``.
  135.  
  136. """
  137. parser = self.create_parser(prog_name, subcommand)
  138. parser.print_help()
  139.  
  140. def run_from_argv(self, argv):
  141. """
  142. Set up any environment changes requested (e.g., Python path
  143. and Django settings), then run this command.
  144.  
  145. """
  146. parser = self.create_parser(argv[0], argv[1])
  147. options, args = parser.parse_args(argv[2:])
  148. handle_default_options(options)
  149. self.execute(*args, **options.__dict__)
  150.  
  151. def execute(self, *args, **options):
  152. """
  153. Try to execute this command, performing model validation if
  154. needed (as controlled by the attribute
  155. ``self.requires_model_validation``). If the command raises a
  156. ``CommandError``, intercept it and print it sensibly to
  157. stderr.
  158. """
  159. show_traceback = options.get('traceback', False)
  160.  
  161. # Switch to English, because django-admin.py creates database content
  162. # like permissions, and those shouldn't contain any translations.
  163. # But only do this if we can assume we have a working settings file,
  164. # because django.utils.translation requires settings.
  165. saved_lang = None
  166. if self.can_import_settings:
  167. try:
  168. from django.utils import translation
  169. saved_lang = translation.get_language()
  170. translation.activate('en-us')
  171. except ImportError, e:
  172. # If settings should be available, but aren't,
  173. # raise the error and quit.
  174. if show_traceback:
  175. traceback.print_exc()
  176. else:
  177. sys.stderr.write(smart_str(self.style.ERROR('Error: %s\n' % e)))
  178. sys.exit(1)
  179.  
  180. try:
  181. self.stdout = options.get('stdout', sys.stdout)
  182. self.stderr = options.get('stderr', sys.stderr)
  183. if self.requires_model_validation:
  184. self.validate()
  185. output = self.handle(*args, **options)
  186. if output:
  187. if self.output_transaction:
  188. # This needs to be imported here, because it relies on
  189. # settings.
  190. from django.db import connections, DEFAULT_DB_ALIAS
  191. connection = connections[options.get('database', DEFAULT_DB_ALIAS)]
  192. if connection.ops.start_transaction_sql():
  193. self.stdout.write(self.style.SQL_KEYWORD(connection.ops.start_transaction_sql()) + '\n')
  194. self.stdout.write(output)
  195. if self.output_transaction:
  196. self.stdout.write('\n' + self.style.SQL_KEYWORD("COMMIT;") + '\n')
  197. except CommandError, e:
  198. if show_traceback:
  199. traceback.print_exc()
  200. else:
  201. self.stderr.write(smart_str(self.style.ERROR('Error: %s\n' % e)))
  202. sys.exit(1)
  203. if saved_lang is not None:
  204. translation.activate(saved_lang)
  205.  
  206. def validate(self, app=None, display_num_errors=False):
  207. """
  208. Validates the given app, raising CommandError for any errors.
  209.  
  210. If app is None, then this will validate all installed apps.
  211.  
  212. """
  213. from django.core.management.validation import get_validation_errors
  214. try:
  215. from cStringIO import StringIO
  216. except ImportError:
  217. from StringIO import StringIO
  218. s = StringIO()
  219. num_errors = get_validation_errors(s, app)
  220. if num_errors:
  221. s.seek(0)
  222. error_text = s.read()
  223. raise CommandError("One or more models did not validate:\n%s" % error_text)
  224. if display_num_errors:
  225. self.stdout.write("%s error%s found\n" % (num_errors, num_errors != 1 and 's' or ''))
  226.  
  227. def handle(self, *args, **options):
  228. """
  229. The actual logic of the command. Subclasses must implement
  230. this method.
  231.  
  232. """
  233. raise NotImplementedError()

BaseCommand

django “如何”系列2:如何编写django-admin 命令的更多相关文章

  1. Django学习系列4:编写第一个简单的应用代码

    首页视图编写 lists/tests.py from django.test import TestCasefrom django.urls import resolvefrom lists.view ...

  2. django “如何”系列4:如何编写自定义模板标签和过滤器

    django的模板系统自带了一系列的内建标签和过滤器,一般情况下可以满足你的要求,如果觉得需更精准的模板标签或者过滤器,你可以自己编写模板标签和过滤器,然后使用{% load %}标签使用他们. 代码 ...

  3. django “如何”系列3:如何编写模型域(model filed)

    django自带很多的域类--CharField,DateField等等--,如果django的这些域都不能满足你精确的要求,那么你可以编写自己的模型域. django自带的域没有和数据库列类型一一对 ...

  4. Django学习系列5:为视图编写单元测试

    打开lists/tests.py编写 """向浏览器返回真正的HTML响应,添加一个新的测试方法""" from django.test i ...

  5. django “如何”系列5:如何编写自定义存储系统

    如果你需要提供一个自定义的文件存储-一个常见的例子便是在远程系统上存储文件-你可以通过定义一个自己的存储类来做这件事情,你将通过一下步骤: 你自定义的存储系统一定是django.core.files. ...

  6. Python+Django+SAE系列教程17-----authauth (认证与授权)系统1

    通过session,我们能够在多次浏览器请求中保持数据,接下来的部分就是用session来处理用户登录了. 当然,不能仅凭用户的一面之词,我们就相信,所以我们须要认证. 当然了,Django 也提供了 ...

  7. Django App(二) Connect Mysql & defualt App admin

    这一篇接着上一篇polls App自动创建admin app.     1.安装数据库 这里的内容从官网看越看越像 EntityFramework的内容.Python支持SQLite,MySql,Or ...

  8. Django实现自定义template页面并在admin site的app模块中加入自定义跳转链接

    在文章 Django实现自定义template页面并在admin site的app模块中加入自定义跳转链接(一) 中我们成功的为/feedback/feedback_stats/路径自定义了使用tem ...

  9. Django之静态文件,中间件,admin后台管理

    静态文件 静态文件的使用 在 网页使用的css文件,js文件和图片等叫做静态文件.1)在项目下新建静态文件夹 static. 2) 配置静态文件所在的物理目录.Settings.py STATIC_U ...

  10. Django学习系列7:使用模板解决“不测试常量”规则,使用模板重构

    之前写的lists/tests.py中的单元测试,要查找特定的HTML字符串,但这不是测试HTML的高效方法. 单元测试规则之一“不测试常量”,编写断言检测HTML字符串中是否有制定的字符串序列,不是 ...

随机推荐

  1. TCP中三次握手建立和四次握手释放以及相关问题

    本文基于个人所学和网上博文所整理,若有不妥处,欢迎留言指出 TCP连接过程中标志位的意义: 字符缩写 描述 SYN 同步序号,表示此报文是一个连接请求或连接接受报文 ACK 确认位,对接收到的报文的确 ...

  2. Spring中事务传播行为类型

    Spring在TransactionDefinition接口中规定了7种类型的事务传播行为,它们规定了事务方法和事务方法发生嵌套调用时事务如何进行传播: 事务传播行为类型 说明 PROPAGATION ...

  3. angularJS入门小Demo2 【包含不用数据库而用data.json格式响应前台的ajax请求方式测试】

    事件绑定: <html> <head> <title>angularJS入门小demo-5 事件指令</title> <script src=&q ...

  4. 2017-7-19-每日博客-关于Linux下的CentOS中文件夹基本操作命令.doc

    CentOS中文件夹基本操作命令 文件(夹)查看类命令 ls--显示指定目录下内容 说明:ls 显示结果以不同的颜色来区分文件类别.蓝色代表目录,灰色代表普通文件,绿色代表可执行文件,红色代表压缩文件 ...

  5. HDU4685:Prince and Princess(二分图匹配+tarjan)

    Prince and Princess Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 65535/32768 K (Java/Othe ...

  6. stout代码分析之五:UUID类

    UUID全称通用唯一识别码,被广泛应用于分布式系统中,让所有的元素具有唯一的标识. stout中UUID类继承自boost::uuids::uuid.api如下: random, 产生一个UUID对象 ...

  7. http-反向代理学习

    主要是学习了反向代理. 结合公司的方向代理使用,然后与同事进行交流,知识还是需要通过交流才能印象深刻,以后多多交流.

  8. Item 28 利用有限制通配符来提升API的灵活性

    <? extends E> 和<? super E>的使用   <? extends E>的使用 Item 26 这是堆栈的公有API: public class ...

  9. 12.13记录//QQDemo示例程序源代码

            笔记的完整版pdf文档下载地址: https://www.evernote.com/shard/s227/sh/ac692160-68c7-4149-83ea-0db5385e28b0 ...

  10. Spring理论基础-面向切面编程

    AOP是Aspect-Oriented Programming的缩写,中文翻译是面向切面编程.作为Spring的特征之一,是要好好学习的. 首先面向切面编程这个名称很容易让人想起面向对象编程(OOP) ...