执行流程
当我们执行django-admin startproject mysite
到底发生了什么?
不管是django-admin还是django-admin.py或者python manage.py,其实最终都是调用了 django.core.management.__init__模块中定义的execute_from_command_line方法。
def execute_from_command_line(argv=None): """ A simple method that runs a ManagementUtility. """ utility = ManagementUtility(argv) utility.execute()
在execute_from_command_line中实际是实例化了一个ManagementUtility,并调用了该实例的execute方法
在ManagementUtility的execute方法中:
- 获取子命令
- 通过自身fetch_command获取子命令处理实例
- 调用该子命令的处理函数handle进行处理
在fetch_command函数中,会调用自身模块中定义的get_commands方法,获取当前Project可以使用的所有Command。 在Django中规定,所有app目录下面中management包中定义commands包,然后commands包中所有以非_开头的模块就是可用的Command
实现一个简单的Command
以django官网给出的closepoll命令为例
from django.core.management.base import BaseCommand, CommandErrorfrom polls.models import Question as Pollclass Command(BaseCommand): help = 'Closes the specified poll for voting' def add_arguments(self, parser): parser.add_argument('poll_id', nargs='+', type=int) def handle(self, *args, **options): for poll_id in options['poll_id']: try: poll = Poll.objects.get(pk=poll_id) except Poll.DoesNotExist: raise CommandError('Poll "%s" does not exist' % poll_id) poll.opened = False poll.save() self.stdout.write(self.style.SUCCESS('Successfully closed poll "%s"' % poll_id))
只要保证INSTALLED_APPS中包含polls应用,我们就可以使用python manage.py closepoll 1
将主键为1的Poll实例关闭掉。