详解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 相关文章推荐
安装dbus-python的简要教程
May 05 Python
Python 常用 PEP8 编码规范详解
Jan 22 Python
Python信息抽取之乱码解决办法
Jun 29 Python
Python实现注册、登录小程序功能
Sep 21 Python
Python 实现中值滤波、均值滤波的方法
Jan 09 Python
15行Python代码实现网易云热门歌单实例教程
Mar 10 Python
解决Django加载静态资源失败的问题
Jul 28 Python
详解Django配置优化方法
Nov 18 Python
Python+Redis实现布隆过滤器
Dec 08 Python
Python过滤掉numpy.array中非nan数据实例
Jun 08 Python
解决Jupyter-notebook不弹出默认浏览器的问题
Mar 30 Python
Python制作春联的示例代码
Jan 22 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生成PDF格式文件并且加密
2015/06/22 PHP
详解php魔术方法(Magic methods)的使用方法
2016/02/14 PHP
layui数据表格自定义每页条数limit设置
2019/10/26 PHP
javascript 进阶篇3 Ajax 、JSON、 Prototype介绍
2012/03/14 Javascript
js判断iframe内的网页是否滚动到底部触发事件
2014/03/18 Javascript
Javascript限制网页只能在微信内置浏览器中访问
2014/11/09 Javascript
node.js集成百度UE编辑器
2015/02/05 Javascript
jquery实现红色竖向多级向右展开的导航菜单效果
2015/08/31 Javascript
基于jQuery全屏焦点图左右切换插件responsiveslides
2015/09/07 Javascript
详解javascript实现瀑布流列式布局
2016/01/29 Javascript
前端框架学习总结之Angular、React与Vue的比较详解
2017/03/14 Javascript
vue2.0实战之使用vue-cli搭建项目(2)
2017/03/27 Javascript
vue bootstrap小例子一枚
2017/06/09 Javascript
vue实现表格数据的增删改查
2017/07/10 Javascript
浅谈mint-ui loadmore组件注意的问题
2017/11/08 Javascript
基于JavaScript实现幸运抽奖页面
2020/07/05 Javascript
vue自定义filters过滤器
2018/04/26 Javascript
修改node.js默认的npm安装目录实例
2018/05/15 Javascript
详解@Vue/Cli 3 Invalid Host header 错误解决办法
2019/01/02 Javascript
Vue3.x源码调试的实现方法
2019/10/13 Javascript
jQuery实现简单弹幕效果
2019/11/28 jQuery
js实现div色块碰撞
2020/01/16 Javascript
vant时间控件使用方法详解
2020/12/24 Javascript
使用python检测手机QQ在线状态的脚本代码
2013/02/10 Python
利用Python生成文件md5校验值函数的方法
2017/01/10 Python
Django+uni-app实现数据通信中的请求跨域的示例代码
2019/10/12 Python
详解Python绘图Turtle库
2019/10/12 Python
Python底层封装实现方法详解
2020/01/22 Python
完美解决pyinstaller打包报错找不到依赖pypiwin32或pywin32-ctypes的错误
2020/04/01 Python
大学班级干部的自我评价分享
2014/02/10 职场文书
写求职信要注意什么问题
2014/04/12 职场文书
活动总结模板
2014/05/09 职场文书
副总经理任命书
2014/06/05 职场文书
2015年保安个人工作总结
2015/04/02 职场文书
把77A收信机改造成收音机
2022/04/05 无线电
Python测试框架pytest核心库pluggy详解
2022/08/05 Golang