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_transactionTrue,则由 BEGIN;COMMIT 包裹)。

  • BaseCommand.create_parser(prog_name, subcommand, **kwargs)

    返回一个 CommandParser 实例,它是 ArgumentParser 的子类,包含一些针对 Django 的个性化设计。你可以自定义这个实例,通过重写此方法,并为 super() 方法传入值为 ArgumentParserkwargs 参数。

  • 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_configstags 均为 None,所以的系统检查项都会被运行。tags 能是一个检查标签的列表,例如 compatibilitymodels

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'),
        ),
    ]

posted @ 2020-01-29 20:09  Lowell  阅读(332)  评论(0编辑  收藏  举报