从零开始devops-django command
我们再使用Django写项目的时候,不可避免的我们会使用到一些manage命令,如django-admin startproject,python manage.py runserver …等命令,然后这些命令就能完成相应的事情。
但有时候Django自带的这些命令也不能满足我们的需求,我们就可以自己编写实现自己的一些需求的命令了。
例如:我们实现一个createuser的命令。我们在终端执行这条命令的时候,就会在数据库创建一个user对象出来。
准备工作:
首先新建一个Django项目,然后新建一个user的app,然后在user的models文件里面编写一个User模型。
from django.db import models
Create your models here.
class User(models.Model):
name = models.CharField(max_length=20)
telephone = models.CharField(max_length=11)
email = models.EmailField()
然后在settings.py文件里面配置好数据库的相关信息,因为我使用的是mysql数据库,所以需要配置,如果使用Django默认的sqlite数据库,就不用配置。
然后执行makemigrations和migrate命令,将模型映射到数据库中。
至此,我们就做好准备工作了。
注意: 这个app必须在settings.py文件中注册。否则会找不到自定义的命令
创建编写manage命令的文件
在Django中,我们想要编写自定义的manage命令,旧的遵循Django的规则来创建文件。
首先,我们在刚才新建的app下面新建一个包,(必须是包,不能是文件夹)这个包的名字为management,必须和这个一模一样,然后在management这个包下面再新建一个包,名字为commands,这样我们就创建好了存放manage命令文件的包,然后在这个包中新建一个python文件,文件的名字就为命令的名字,例如,我创建 了一个selfcommand的文件,也就是我创建的命令的名称为selfcommand。
这个app最终的目录结构为:
这样,我们就创建好了编写代码的文件。
编写代码
首先,我们创建一个名为Command的类,这个类的名字必须为这个。然后继承自django.core.management.BaseCommand类。
from django.core.management import BaseCommand
class Command(BaseCommand):
help = '创建一个user用户'
def handle(self, *args, **options):
pass
1
2
3
4
5
6
7
help这个变量可写可不写,这个变量的作用是在使用命令的-h或--help参数时会显示出来的文字,在这里我们可以写入这条命令的作用,描述。
handle函数:这个函数是必须写的函数,我们使用这条命令的时候就会执行这个函数里面的代码。
因为我们这条命令的主要功能是创建一个user用户,所以我们首先导入User对象,然后开始编写代码。
from user.models import User
1
class Command(BaseCommand):
help = '创建一个user用户'
def handle(self, *args, **options):
User.objects.create(name='aaa',telephone='1111111111',email='aaa@qq.com')
self.stdout.write('用户创建成功')
注意: 这里我们一般不使用print()打印信息,而是使用self.stdout.write来打印信息。
这样,我们就编写好了一条简单的创建一个user对象的命令。然后我们在终端执行命令:
python manage.py selfcommand(在创建的包的下面的文件的名字)
1
然后在终端就会打印出用户创建成功的信息,然后我们去数据库也能查看到创建的user对象的信息
但是,这个时候就会出现一个比较尴尬的问题,就是我们创建user用户的时候,肯定需要别人自己输入信息,但是我们并没有让别人自己输入信息,而是直接创建一个定死的user对象。所以,这个时候就需要我们给这条命令添加参数了。
如果想给命令添加参数,那么我们在这个类中就得新建一个方法,名为add_argument。
class Command(BaseCommand):
help = '创建一个user用户'
def add_arguments(self, parser):
parser.add_argument('name',help="指定name字段") # name 必须参数,输入的第一个参数的值将赋值给name,必须参数
parser.add_argument('-t','--telephone',help="指定telephone字段") # 可选参数 -t 或 --telephone -t是简写形式。
def handle(self, *args, **options):
name = options['name']
if options['telephone']:
telephone = options['telephone']
else:
telephone = '11111111111'
User.objects.create(name=name,telephone=telephone,email='aaa@qq.com')
self.stdout.write('用户创建成功')
在上面我们定义了两个参数,一个必须参数,一个可选参数,因此,我们再使用这条命令的时候必须传入name参数,而telephone参数可以不传,然后我们在handel方法中对得到的参数进行了处理。
python manage.py selfcommand ccc
1
python manage.py selfcommand ddd -t 18888888888
1
我们也可以使用python manage.py -h查看这条命令的帮助,也能看到我么自定义的参数。
我们再使用命令的时候,特别在使用一些刚接触不久的命令的时候,很容易出现非正确的使用命令,那么我们就需要抛出一个异常,告诉他命令使用错误了。
首先我们的导入一个类
from django.core.management import CommandError
1
例如,我们在传入手机号码的时候,如果位数超过了11位,那么我们就抛出一个异常:
def handle(self, *args, **options):
name = options['name']
if options['telephone']:
telephone = options['telephone']
if len(telephone) >= 11:
raise CommandError("手机号码不能超过11位")
else:
telephone = '11111111111'
User.objects.create(name=name,telephone=telephone,email='aaa@qq.com')
self.stdout.write('用户创建成功')
这里,我们就使用到了CommandError类来抛出了异常,从而保证了我们程序的健壮性了。
当用户输入的电话号码长度大于11位的时候,就会抛出一个异常而终止程序。
注意: 我们在参数中输入的值,在handel函数中都是以字符窜的形式得到,就算我们输入的是整数,也会变成字符窜的形式,如果想得到整数形式的值,我们可以在add_argument()中添加type=int参数。
示例:
parser.add_argument('id',help="user对象的id",type=int)