自定义Django-admin管理命令

django本身是有一些django-admin命令的,他们都是基于manage.py来使用的。

比如,python3 manage.py createsuperuser xxx

           python3 manage.py makemigrations

           python3 manage.py migrate

           python3 manage.py dumpdata path.modle --pk num  # 将数据库中表名为modle,pk为 unm的数据导出来

           python3 manage.py loaddata xxx.json   # 将有表数据的json文件导入数据库

等等...

但是,更多时候,我们对于工程的操作,往往是需要自己定义一些命令的,以更方便的操控工程。所以,就有了自定义 django-admin 管理命令一说。

举个简单的例子,fab 是可以用作在远程机器上执行命令的一个工具,有时候,我们会将部署服务的命令集成到 fabfile.py,这样,就可以使用 fab 命令去完成服务的部署了。但是 fab 往往是单独存在的,需要我们在terminal直接输入 fab 命令,这样跟整个工程的粘度,就不是很大了。所以我们会考虑将 fab 集成到 django-admin 里, 通过 python3 manage.py fab task:param remote_machine_address,的这类命令,直接实现服务的部署操作。

对于自定义的 django-admin 的创建,本身并不难:

首先:自定义的Django-admin管理命令本质上是一个python脚本文件,它的存放路径必须遵循一定的规范,一般位于app/management/commands目录。整个文件夹的布局如下所示:

app01/
    __init__.py
    models.py
    management/
        __init__.py
        commands/
            __init__.py
            _private.py # 以下划线开头文件不能用作管理命令
            my_commands.py # 这个就是自定义的管理命令脚本,文件名即为命令名
    tests.py
    views.py

这个布局是不能变的。这里注意,commands 文件夹下可以有多个py文件,基本上每个py文件的文件名,就是自定义管理命令的命令名称。所以,在一个commands里是可以创建出多条django-admin命令的。另外就是commands文件夹中,下划线开头的py文件,是不会被系统认定为django-admin命令的,所以像这种类型的文件都可以用来存储一些方法文件。

django-admin的具体定义:

每一个自定义的管理命令本质是一个Command类, 它继承了Django的Basecommand或其子类, 主要通过重写handle()方法实现自己的业务逻辑代码,而add_arguments()则用于帮助处理命令行的参数,如果运行命令时不需要额外参数,可以不写这个方法。

from django.core.management.base import BaseCommand

class Command(BaseCommand):
    # 帮助文本, 一般备注命令的用途及如何使用。
    help = 'Some help texts'

    # 处理命令行参数,可选
    def add_arguments(self, parser):
       pass

    # 核心业务逻辑
    def handle(self, *args, **options):
        pass

这里注意 add_arguments() 这个函数中的参数,parser,它是个特殊的对象,使用方法类似于下面的演示。

from django.core.management.base import BaseCommand

class Command(BaseCommand):
    # 帮助文本, 一般备注命令的用途及如何使用。
    help = "Print Hello World!"

    # 给命令添加一个名为name的参数
    def add_arguments(self, parser):
        parser.add_argument('name')

    # 核心业务逻辑,通过options字典接收name参数值,拼接字符串后输出
    def handle(self, *args, **options):
        msg = 'Hello World ! '+ options['name']
        self.stdout.write(msg) 此时当你再次运行`python manage.py hello_world John`命令时,你将得到如下输出结果:

其实,关于这个参数,还有更多的用法,例如:

import datetime
import logging
import subprocess
import textwrap

from django.core.management.base import BaseCommand


DEFAULT_DAYS = 7
START_DATE = datetime.datetime(2018, 6, 24)
_BUILD_TREE = "/bldmnt/storage61/release"
_TERMINAL_METASTATES = ('failed')

logger = logging.getLogger('webapps')


class Command(BaseCommand):

    """
    This command takes 1 argument, buildtype
    """
    help = textwrap.dedent(__doc__).strip()

    def add_arguments(self, parser):
        # Named (optional) arguments
        parser.add_argument(
            '-b', '--buildtype',
            type=str,
            choices=('sb', 'ob'),
            required=True,
            help='Build type either SB or OB',
        )
        parser.add_argument(
            '--days', '-d',
            dest="days",
            default=DEFAULT_DAYS,
            help='Number of days to check storage. Default: %(default)s.',
            type=int,
        )

    def handle(self, *args, **options):
        """
        Entry point when management command is executed.
        """
        total_size = 0
        buildtype = options['buildtype']
        INTERVAL = options['days']
        END_DATE = START_DATE + datetime.timedelta(days=INTERVAL)
        DAYS_INTERVAL = datetime.timedelta(days=1)
        current_start = START_DATE

他完全和 python 的 parser 这个模块,用法一致。

关于这个模块的具体参数,及用法可以参考:

python之parser.add_argument()用法——命令行选项、参数和子命令解析器_夏普通的博客-CSDN博客_parser.add_argument(

添加 add_arguments 的方式,在写handle的时候,都是通过,options 取的,是当字典来用的。另外提一种,不添加 add_arguments 方法的方式,直接安位传参。

import os

from django.conf import settings
from django.core.management.base import BaseCommand


class Command(BaseCommand):
    def handle(self, *args, **options):
        os.system('%s %s' % (settings.FAB_CMD, ' '.join(args)))

    def run_from_argv(self, argv):
        parser = self.create_parser(argv[0], argv[1])
        options = parser.parse_args([])
        cmd_options = vars(options)
        cmd_options.pop('args', ())
        self.execute(*argv[2:], **cmd_options)

    def print_help(self, prog_name, subcommand):
        os.system('%s --help' % settings.FAB_CMD)

只需要重写 run_from_argv 这个方法,这样会让 opthions 的内容变为空字典。在manage.py 后使用的时候,就直接按位传参就可以了。

另外,再扯点fab命令,首先下载 fabric 包。

然后就是 fabric 的使用,命令:fab --fabfile  xxx.py   task:param   remote_machine_address

fab的使用,是必须有个配置文件的,这个文件放到工程的根目录且名为 fabfile.py 的时候,那么使用fab命令就可以不给 --fabfile 参数,如果是放到其他位置,或是叫其他名称,那就需要给 --fabfile 参数,以明确指定用哪个fab文件。

对fab的一些参数的说明,可以参考:Python Fabric模块详解 - 君无颜 - 博客园

看一个真实的fabfile:

from fabric.api import env, sudo, task, run
from fabric.context_managers import remote_tunnel, cd
from fabric.utils import puts



PROJECT_NAME = 'buildapi'
SERVICE_ROOT_SB = '/service/buildapi-sb'
SERVICE_ROOT_OB = '/service/buildapi-ob'
BUILDAPI_ROOT = '/build/mts/buildapi'

# Settings:
env.roledefs = {
    'sjc31': [
        
    ],
    'wdc': [
        
    ],
    'stage': [
        '
    ],
}
# Note: task(s) will be executed on hosts in the order listed
env.roledefs['all'] = (env.roledefs['wdc'] + env.roledefs['sjc31'])

set_common_settings()

# Tasks:
all = get_role_setter('all')
sjc31 = get_role_setter('sjc31')
wdc = get_role_setter('wdc')
stage = get_role_setter('stage')

sync = get_sync_task(PROJECT_NAME, BUILDAPI_ROOT)

restart_sb = get_restart_task(PROJECT_NAME, SERVICE_ROOT_SB)
restart_ob = get_restart_task(PROJECT_NAME, SERVICE_ROOT_OB)


@task
def deploy(rev=None, force=False, tunnel=False):
    """Deploy buildapi.  Usage: deploy[:rev=REVISION][:force=1][:tunnel=1]"""
    paragraph()
    puts(hl('Deploying buildapi...'))
    if sync(rev):
        py38env(tunnel)
        restart_sb(force)
        restart_ob(force)
    else:
        puts(warn('No need to restart.'))


@task
def py38env(tunnel=False):
    """Create/upgrade the py38 virtualenv.    Usage: py38env[:tunnel=1]"""
    if tunnel:
        tunnel_port = 10210
        with remote_tunnel(remote_port=tunnel_port,
                           local_host="build-artifactory",
                           local_port=80):
            sudo('/usr/bin/make -C %s -f ./py38env.mk '
                 'BUILD_ARTIFACTORY=127.0.0.1:%s'
                 % (BUILDAPI_ROOT, tunnel_port))
    else:
        sudo('/usr/bin/make -C %s -f ./py38env.mk' % BUILDAPI_ROOT)
    deploy_check()


@task
def deploy_check():
    """Deploy test for django admin check command if setup correctly"""
    with cd(BUILDAPI_ROOT):
        run('./manage_sb.sh check')

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
"django-admin ui" 这个命令Django 中并不存在。可能是你错误地输入了这个命令,或者你可能引用的是过时的文档或教程。 Django命令行工具是 "django-admin" 或 "manage.py"。这些命令行工具用于执行各种 Django 相关的任务,例如创建新的 Django 项目、运行开发服务器、执行数据库迁移等。 如果你想在 Django 中使用图形用户界面 (GUI),可以考虑使用 Django 的第三方库或插件来实现。例如,Django Suit 是一个常用的 Django 插件,它提供了一个漂亮和功能强大的管理界面。你可以通过安装它,然后在你的 Django 项目中进行配置和使用。 安装 Django Suit 可以使用 pip 命令: ``` pip install django-suit ``` 安装完成后,在你的 Django 项目的 settings.py 文件中加入以下配置: ```python INSTALLED_APPS = [ ... 'suit', ... ] SUIT_CONFIG = { 'ADMIN_NAME': 'Your Admin Name', 'MENU': ( 'sites', {'app': 'auth', 'icon':'icon-lock', 'models': ('user', 'group')}, {'label': 'Custom Label', 'icon':'icon-cog', 'models': ('app.model1', 'app.model2')}, {'label': 'Custom Label', 'icon':'icon-cog', 'url': '/custom-url/'}, ), } ``` 这样,你就可以在项目的管理界面中看到一个更漂亮和直观的界面。 相关问题: 1. Django 有哪些其他的第三方库或插件可以提供图形用户界面? 2. 如何自定义 Django管理界面,以满足特定的需求? 3. 有没有其他方法可以在 Django 中实现图形用户界面,而不使用第三方库?
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值