django编写自定义的脚本文件
介绍
每个app下都可以有一个management/commands
目录。Django将manage.py
为该目录中每个名称都不以下划线开头的Python模块注册一个命令。官网
该模块mytest.py只有一个需求–它必须定义一个类 Command
并继承BaseCommand
或其 子类之一。
mytest.py如下:
from django.core.management.base import BaseCommand, CommandError
from polls.models import Question as Poll
class Command(BaseCommand):
help = 'Closes the specified poll for voting'
# 添加额外的参数
def add_arguments(self, parser):
parser.add_argument('poll_ids', nargs='+', type=int)
# 重写父类的handle方法,继承BaseCommand必须重写该方法,该方法就是执行的代码
def handle(self, **options):
for poll_id in options['poll_ids']:
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))
使用python manage.py mytest
来执行该脚本文件
Command对象
BaseCommand
继承该类必须重写handle方法。
属性
-
BaseCommand.help
该命令的简短描述,当用户运行该命令时,它将显示在帮助消息中 。
python manage.py help <command>
-
BaseCommand.missing_args_message
如果您的命令定义了必需的位置参数,则可以自定义在缺少参数的情况下返回的消息错误。默认输出为
argparse
(“参数过多”)。 -
BaseCommand.output_transaction
指示命令是否输出SQL语句的布尔值;如果
True
,输出将自动用BEGIN;
和 包装COMMIT;
。默认值为False
。 -
BaseCommand.requires_migrations_checks
一个布尔值;if
True
,如果磁盘上的迁移集与数据库中的迁移不匹配,则该命令将显示警告。警告不会阻止命令执行。默认值为False
。 -
BaseCommand.requires_system_checks
一个布尔值;如果为
True
,则在执行命令之前将检查整个Django项目是否存在潜在问题。默认值为True
。 -
BaseCommand.style
实例属性,可在写入
stdout
或时帮助创建彩色输出stderr
。例如:self.stdout.write(self.style.SUCCESS('...'))
方法
BaseCommand
有很多方法可供重写,不过仅有 handle()
是必须实现的。
子类中实现构造器
若 BaseCommand
的子类实现了 __init__
方法,那么就必须调用 BaseCommand
的 __init__
:
class Command(BaseCommand):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
# ...
-
BaseCommand.handle(*args, **options)
重要命令的实际逻辑处理。子类必须实现此方法。此方法可能会返回一个字符串,输出至
stdout
(若output_transaction
为True
,则由BEGIN;
和COMMIT
包裹)。 -
BaseCommand.create_parser(prog_name, subcommand, **kwargs)
返回一个
CommandParser
实例,它是ArgumentParser
的子类,包含一些针对 Django 的个性化设计。你可以自定义这个实例,通过重写此方法,并为super()
方法传入值为ArgumentParser
的kwargs
参数。 -
BaseCommand.add_arguments(parser)
添加命令行转换参数的入口,用于处理传给命令行的参数。自定义命令需要重写此方法,并同时添加命令接受的位置参数和可选参数。直接使用
BaseCommand
的子类时无需调用super()
。 -
BaseCommand.get_version()
返回 Django 版本,内置 Django 命令必须正确返回。用户实现的命令可以重写此方法返回自己的版本。
-
BaseCommand.execute(*args, **options)
试着执行此命令,如果需要的话,进行系统检查(由
requires_system_checks
控制)。若命令抛出CommandError
,这会导致命令中断,并将错误输出至 stderr。 -
BaseCommand.check(app_configs=None, tags=None, display_num_errors=False)
利用系统检查框架校验 Django 项目是否存在隐含的问题。严重的问题会抛出
CommandError
;警告会输出至 stderr;次要通知输出至 stdout。若app_configs
和tags
均为None
,所以的系统检查项都会被运行。tags
能是一个检查标签的列表,例如compatibility
或models
。
BaseCommand子类
AppCommand
管理命令接受一个或多个应用标签参数,并对每项应用做某些事。
子类必须实现 handle_app_config()
,而不是 handle()
。此方法会为每个应用调用一次。
-
AppCommand.handle_app_config(app_config, **options)
为
app_config
运行命令,这会是AppConfig
的实例,并指向命令行给定的应用标签。
LabelCommand
一个管理命令,从命令行接受一个或任意多个参数(labels),并针对每项做些事情。
子类必须实现 handle_label()
,而不是 handle()
。此方法会为每个应用调用一次。
-
LabelCommand.label
一个字符串,介绍了传递给命令的任意多个参数。此字符串用于命令的用法文本和错误消息。默认为
'label'
。 -
LabelCommand.handle_label(label, **options)
运行
label
指定的命令动作,由命令行传入的字符串。
在migrations文件中执行python脚本
# Generated by Django 3.0.8 on 2021-09-02 17:31
from django.db import migrations, models
import django.db.models.deletion
def update_xxx(apps, schema_editor):
ModelObj = apps.get_model("appName", "ModelName")
obj_qs = ModelObj.objects.all()
class Migration(migrations.Migration):
dependencies = [
('xxx', '0024_auto_20210901_0850'),
('xxx', '0036_auto_20210826_1155'),
]
operations = [
migrations.RunPython(update_xxx),
migrations.AlterField(
model_name='xxx',
name='xxx',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT,
to='xxx', verbose_name='xxx'),
),
]