每个学习django框架的童鞋都知道如何创建一个django项目和app,这都离不开django-admin.py和manage.py。 django-admin.py是Django的一个用于管理任务的命令行工具,创建project就需要该命令行工具,另外,在每一个Django project中都会有一个manage.py。

    想想当初,刚刚接触这些东西的时候,只知道死记硬背(想必很多人跟我一样),其实帮助工具要利用好,就像linux命令,有时候你知道某个命令但是忘记了它参数的含义,可以用帮助工具,用带--help参数执行一下命令,就知道了用法了,当然能记住更好,熟能生巧,没记住也可以利用这些工具。django的django-admin.py和manage.py也有帮助工具(或者说帮助命令),django-admin.py help或python manage.py help,就会知道对应的有哪些命令,比如runserver,startapp,shell等内置命令。其实manage命令可以扩展,我之前也不知道,是今天技术经理叫我写脚本时,我本来想利用MySQLdb模块写脚本,他跟我说可以自定义manage.py扩展命令,快些,而且也可以部署定时计划任务。然后就是找资料学习,编写,发现其实也挺简单的。后来想想,这种方法确实简单便捷很多,因为MySQLdb模块连接数据库,查询数据库都是用原始的sql语句,而且返回的结果也比较奇葩(个人觉得奇葩,返回的是嵌套式元组,类似于(( , , , ,),( , , , ,),)这种,利用起来不太方便,当然它也有优势,查询速度快),所以用起来比较别捏,我们更喜欢用QuerySet API查询数据库,用起来方便。下面来讲讲如何定义自己的manage.py扩展命令吧。

    注册manage命令只需要在app中创建一个management/commands路径,Django会自动将该路径下不以’_’开头的文件注册为manage.py的命令。

如下路径:

wKioL1ekrVnh45NUAAAY0YMXGDA977.png-wh_50

    

要注意:__init__.py不能少,没当建一个文件夹(Directory)是,要想django能识别它,
就要在其目录下加一个__init__.py文件,哪怕是空的也行
对于注册的manage.py命令closepicking仅仅需要满足将一个条件 —— 其必须定义一个继承自
BaseCommand或者其子类的Command类
from datetime import datetime
from django.core.management.base import BaseCommand
class Command(BaseCommand):
    def handle(self, days=10, *args, **kwargs):
        from stock.models import StockPicking
        current_date = datetime.now()
        pickings = StockPicking.objects.filter(
          type='out',
          state='confirmed',
          create_time__range=(datetime(2016,  1, 1), current_date),
          is_closed=False)
        for p in pickings:
            if not p.date:
                p.date = _fetch_date_from_stockmove(p)
            date_delta = current_date - p.date
            if date_delta.days < days:
                continue
            p.is_closed = True
            p.save()

def _fetch_date_from_stockmove(picking):
    from stock.models import StockMove
    stockmoves = StockMove.objects.filter(picking=picking, 
    state='confirmed')
    try:
        rv = stockmoves[0].date_confirmed
    except IndexError:
        rv = None
    if not rv:
        rv = datetime.now()
    return rv


这个例子是设置对象的is_closed字段为1。

在测试无误的情况下,此时在执行python manage.py help,你会发现多了一个closepicking命令,说明注册成功

当然Command提供了一个方法用来增加可选的参数——add_arguments()

在上面类Command里加一个add_arguments()函数,如下

def add_arguments(self, parser):
    parser.add_argument('poll_id', nargs='+', type=int)
    parser.add_argument('--delete',
        action='store_true',
        dest='delete',
        default=False,
        help='Delete poll instead of closing it')

然后在handle()函数里价格条件判读句,如下

if options['delete']:
   p.delete()
   
 这种设计就是传入参数如–delete
 
 
 由于技术有限,错误支持请多多指教!