详解Python的Django框架中manage命令的使用与扩展


Posted in Python onApril 11, 2016

【简介】

django-admin.py是Django的一个用于管理任务的命令行工具。本文将描述它的大概用法。

另外,在每一个Django project中都会有一个manage.py。manage.py是对django-admin.py的简单包装,它额外帮助我们做了两件事情:

它将你的project的包放到sys.path中
它将DJANGO_SETTINGS_MODULE环境变量设置为了你的project的setting.py文件的位置。
如果你是通过setup.py工具来安装Django的,那么django-admin.py脚本应该在你的系统目录中。如果不存在,你可以到你的python安装目录下的site-package/django/bin中去找找看。

通常来说,如果你经常是在一个独立的Django project里工作,那么使用manage.py会更方便一些。但如果你有很多Django project,那么可以使用django-admin.py,同时需要经常变更DJANGO_SETTINGS_MODULE或使用?settings选项来设置不同的setting.py。

本文中都会使用django-admin.py来给大家做演示,但所有的例子,都也可以使用manage.py来实现。

【用法】

djang-admin.py的语法为:

django-admin.py <subcommand> [options]
manage.py <subcommand> [options]

其中,subcommand是子命令;options是可选的,可以有0个到多个option。

获得帮助的方法是使用help这个命令,共有两种方法:

1 运行django-admin.py help会显示用法信息,并给出所有可用的subcommand列表

2 运行django-admin.py help <subcommand>会显示特定的subcommand的描述信息,以及所有可用的options

运行django-admin.py ?version可以显示django的版本号。

如果使用django-admin.py时加入?verbosity,则会显示大量通知信息和调试信息。

【runfcgi】- subcommand

用于启动一个支持FastCGI协议的进程,以便接收WebServer发来的请求。可以使用flup作为Python FastCGI模块。

runfcgi的选项如下:

  • protocol:用于设定所使用的cgi协议,包括fcgi、scgi和ajp等,默认是fcgi。
  • host:用于设置监听所在的主机名
  • port:用于设定监听的端口
  • socket:用于设置监听的UNIX socket
  • method:可以设置为prefork或threaded。默认是prefork。
  • maxrequests:一个子进程所能处理的请求的最大数量。一旦超过此数量,则子进程会被kill掉,并创建一个新进程。设置为0意味着对子进程无限制。
  • maxspare:空闲进程/线程的最大数量
  • minspare:空闲进程/线程的最小数量
  • maxchildren:进程/线程数的硬限制值
  • daemonize:为boolean值,表示是否放到后台运行。
  • pidfile:设置一个文件,用于将产生的PID信息写入。
  • workdir:用于设置工作目录
  • debug:为boolean值,用于设置是否开启flup的信息跟踪
  • outlog:用于设置将标准输出写入到的文件
  • errlog:用于设置将标准错误输出写入到的文件
  • umask:用于设置在进程运行时所用的umask。默认是022.

举例来说:

django-admin.py runfcgi socket=/tmp/fcgi.sock method=prefork daemonize=true \
  pidfile=/var/run/django-fcgi.pid

此命令用于在后台启动fastCGI,并将pid写入文件中。

【runserver】- subcommand

用于在本机启动一个轻量级的Web server。默认情况下,这个server会在127.0.0.1上监听8000端口。你也可以传入参数来改变默认配置。

如果你并非特权用户,那么你所设置的端口号不能低于1024,因为小于1024的端口已经被系统预定了。

一定不要用这个轻量级Server作为你的生产环境下的Server,因为它只能用于开发自测阶段。它既没有安全审计功能,而且又是单线程的。

另外,每来一个请求,Web Server都会从新载入一遍Python代码,因此如果你的代码有改动,不需要重启Web Server即可生效。

你可以在一个project中启动多个fastcgi server,只要设置不同的端口就可以了。

如果你设定的IP为默认的127.0.0.1,那么你只能从本机的浏览器来登录浏览,无法从其他机器来访问。为了能让其他机器浏览本机,需要将IP设置为目标机器的IP或者0.0.0.0(IPv4地址)或::(IPv6地址)。

在指定IP地址时,也可以使用主机名或域名来代替。

【shell】- subcommand

用于开启一个Python解释器。

Django默认会使用IPython或bpython。但如果你没有安装它们或者就是要使用简装版的话,可以加上?plain选项,即:

django-admin.py shell --plain

【startapp】- subcommand

在当前路径或指定目录下创建一个Django app的文件夹结构。

默认情况下,文件夹中会包括module.py文件和其他必备文件。

如下命令用于在特定目录下创建一个app:

django-admin.py startapp myapp /Users/jezdez/Code/myapp

【startproject】- subcommand

In Django, Projects can have many apps. Apps can be shared among many projects.

在当前目录或指定位置创建一个Django project文件夹结构。

默认情况下,新文件夹中会包括manage.py和一系列必备文件。

目标位置参数是可选的参数,可以设置project所创建的路径。

例如,如下命令可以在指定位置创建一个project:

django-admin.py startproject myproject /Users/jezdez/Code/myproject_repo

和startapp命令一样,--template命令准许你指定一个文件夹,文件路径,或者一个自定义项目模板的链接,关于对项目模板的支持可以查看startapp的文档

下面的例子,在创建myproject项目的时候,会在指定的路径查找模板

django-admin.py startproject --template=/users/jezdez/code/my_project_template myproject

When Django copies the project template files, it also renders certain files through the template engine: the files whose extensions match the --extension option (py by default) and the files whose names are passed with the --name option. The template context used is:

Any option passed to the startproject command
project_name -- the project name as passed to the command
project_directory -- the full path of the newly created project
secret_key -- a random key for the SECRET_KEY setting
Please also see the rendering warning as mentioned for startapp.

syncdb

django-admin.py syncdb

这个命令将为以安装的(INSTALLED_APPS)apps创建数据表,如果数据表还没创建的话。

【扩展manage命令】
我们都用过Django的django-admin.py和manage.py。django-admin.py是一个命令行工具,可以执行一些管理任务,比如创建Django项目。而manage.py是在创建每个Django project时自动添加在项目目录下的,只是对manage.py的一个简单包装,其功能是将Django project放到sys.path目录中,同时设置DJANGO_SETTINGS_MODULE环境变量为当前project的setting.py文件。

django-admin.py调用django.core.management来执行命令:

#!/usr/bin/env python
from django.core import management
  
if __name__ == "__main__":
  management.execute_from_command_line()

excute_from_command_line()函数会根据命令行参数解析出命令的名称,根据命令名称调用相应的Command执行命令。Command位于各个管理模块的commands模块下面。

所谓管理模块,是指在app模块下的名字为management的模块。Django通过django.core.management.find_management_module函数发现"管理模块":

django.core.management.find_management_module()
def find_management_module(app_name):
  """
  Determines the path to the management module for the given app_name,
  without actually importing the application or the management module.

  Raises ImportError if the management module cannot be found for any reason.
  """
  parts = app_name.split('.')
  parts.append('management')
  parts.reverse()
  part = parts.pop()
  path = None

然后通过django.core.management.find_commands函数找到命令类。find_commands函数会在管理模块下查找.py文件,并将.py文件的名称匹配到命令名称:

def find_commands(management_dir):
  """
  Given a path to a management directory, returns a list of all the command
  names that are available.

  Returns an empty list if no commands are defined.
  """
  command_dir = os.path.join(management_dir, 'commands')
  try:
    return [f[:-3] for f in os.listdir(command_dir)
      if not f.startswith('_') and f.endswith('.py')]
  except OSError:
  return []

最后,通过django.core.management.load_command_class函数加载该.py文件中的Command类:

def load_command_class(app_name, name):
  """
  Given a command name and an application name, returns the Command
  class instance. All errors raised by the import process
  (ImportError, AttributeError) are allowed to propagate.
  """
  module = import_module('%s.management.commands.%s' % (app_name, name))
  return module.Command()

在执行命令的时候,会执行相应Command类的handle方法。所有的Command类都应该是django.core.management.base.BaseCommand的直接或间接子类。

原理搞清楚了,扩展manage命令就很容易了。创建一个app并加入到settings的INSTALLED_APPS中,在该app下面创建management.commands模块,并创建hello.py文件:

from django.core.management.base import BaseCommand, CommandError
from django.db import models
#from placeholders import *
import os
  
class Command(BaseCommand):
   def handle(self, *args, **options):
     print 'hello, django!'

就可以使用hello命令了:

$ python manage.py hello
hello, django!
Python 相关文章推荐
跟老齐学Python之通过Python连接数据库
Oct 28 Python
关于Python如何避免循环导入问题详解
Sep 14 Python
Python数据结构与算法之使用队列解决小猫钓鱼问题
Dec 14 Python
用Eclipse写python程序
Feb 10 Python
便捷提取python导入包的属性方法
Oct 15 Python
python函数与方法的区别总结
Jun 23 Python
flask框架路由常用定义方式总结
Jul 23 Python
Python笔记之代理模式
Nov 20 Python
python使用gdal对shp读取,新建和更新的实例
Mar 10 Python
Python实现列表中非负数保留,负数转化为指定的数值方式
Jun 04 Python
详解Python生成器和基于生成器的协程
Jun 03 Python
解决pycharm安装scrapy DLL load failed:找不到指定的程序的问题
Jun 08 Python
对Python的Django框架中的项目进行单元测试的方法
Apr 11 #Python
使用Python的Django框架结合jQuery实现AJAX购物车页面
Apr 11 #Python
Python的Django REST框架中的序列化及请求和返回
Apr 11 #Python
python中的错误处理
Apr 10 #Python
python脚本实现xls(xlsx)转成csv
Apr 10 #Python
Python使用gensim计算文档相似性
Apr 10 #Python
Python调用SQLPlus来操作和解析Oracle数据库的方法
Apr 09 #Python
You might like
PHP 模拟登陆MSN并获得用户信息
2009/05/16 PHP
php header示例代码(推荐)
2010/09/08 PHP
基于Swoole实现PHP与websocket聊天室
2016/08/03 PHP
PHP操作Redis常用技巧总结
2018/04/24 PHP
采用CSS和JS,刚好我最近有个站点要用到下拉菜单!
2006/06/26 Javascript
javascript获取当前ip的代码
2009/05/10 Javascript
javascript 传统事件模型构造的事件监听器实现代码
2010/05/31 Javascript
JavaScript Accessor实现说明
2010/12/06 Javascript
JavaScript 大数据相加的问题
2011/08/03 Javascript
jQuery实现的向下图文信息滚动效果
2015/05/03 Javascript
浅谈javascript 函数表达式和函数声明的区别
2016/01/05 Javascript
JavaScript实现点击按钮复制指定区域文本(推荐)
2016/11/25 Javascript
Bootstrap和Java分页实例第一篇
2016/12/23 Javascript
使用smartupload组件实现jsp+jdbc上传下载文件实例解析
2017/01/05 Javascript
Ionic2调用本地SQlite实例
2017/04/22 Javascript
Nodejs 复制文件/文件夹的方法
2017/08/24 NodeJs
angular 实时监听input框value值的变化触发函数方法
2018/08/31 Javascript
nodejs实现范围请求的实现代码
2018/10/12 NodeJs
详解Express笔记之动态渲染HTML(新手入坑)
2018/12/13 Javascript
在vue+element ui框架里实现lodash的debounce防抖
2019/11/13 Javascript
vue中keep-alive内置组件缓存的实例代码
2020/04/16 Javascript
[02:18]DOTA2英雄基础教程 育母蜘蛛
2014/01/20 DOTA
Python学习之asyncore模块用法实例教程
2014/09/29 Python
Python做文本按行去重的实现方法
2016/10/19 Python
python如何使用unittest测试接口
2018/04/04 Python
python 定时修改数据库的示例代码
2018/04/08 Python
Python+unittest+requests+excel实现接口自动化测试框架
2020/12/23 Python
一款纯css3制作的2015年元旦雪人动画特效教程
2014/12/29 HTML / CSS
高三体育教学反思
2014/01/29 职场文书
服装创业计划书范文
2014/02/05 职场文书
保密承诺书
2014/03/27 职场文书
技术岗位竞聘演讲稿
2014/05/16 职场文书
写给孩子的新学期寄语
2015/02/27 职场文书
开工典礼致辞
2015/07/29 职场文书
《富饶的西沙群岛》教学反思
2016/02/16 职场文书
微信小程序中wxs文件的一些妙用分享
2022/02/18 Javascript