详解django实现自定义manage命令的扩展

下面我将详细讲解“详解django实现自定义manage命令的扩展”的完整攻略,过程中包含两条示例说明。

什么是manage.py命令

在Django中,我们一般使用manage.py命令行工具来进行项目相关操作,例如启动服务器、创建数据库、添加管理员账户等等。

为什么需要自定义manage.py命令

虽然Django自带的manage.py命令已经非常丰富,但是有时候我们需要自己创建一些自定义的命令来解决项目中的特定问题,或者简化一些重复性的操作。这时候就需要我们自定义manage.py命令了。

如何实现自定义manage.py命令

要实现自定义manage.py命令,需要在Django项目中创建一个命令文件,然后在该文件中定义我们需要的命令。接下来分别讲解如何创建命令文件和如何定义自定义命令:

创建命令文件

先在Django项目的根目录下创建managementcommands文件夹,然后在commands文件夹下创建一个Python文件,命名为我们所需要的命令名,例如my_command.py

命令文件的目录结构如下:

.
└── my_project/
    ├── manage.py
    ├── my_app/
    ├── my_project/
    │   ├── __init__.py
    │   ├── settings.py
    │   ├── urls.py
    │   └── wsgi.py
    └── my_command/
        ├── __init__.py
        └── commands/
            ├── __init__.py
            └── my_command.py

定义自定义命令

my_command.py中定义一个类,继承自django.core.management.base.BaseCommand。该类必须包括handle方法,这个方法是自定义命令的核心实现。

例如,下面是一个读取某文件内容到数据库的命令:

from django.core.management.base import BaseCommand
from my_app.models import MyModel

class Command(BaseCommand):
    def handle(self, *args, **kwargs):
        # 读取文件
        with open('file.txt', 'r') as f:
            content = f.read()
            # 写入数据库
            MyModel.objects.create(content=content)

类中的其他方法和属性也可以被重载和定义,例如help属性可以定义命令帮助信息。

注册自定义命令

最后,在my_app下的__init__.py文件中添加如下代码:

# my_app/__init__.py
default_app_config = 'my_command.apps.MyCommandConfig'

接下来,在my_command下新建一个apps.py文件,注册自定义命令。

from django.apps import AppConfig

class MyCommandConfig(AppConfig):
    name = 'my_command'
    verbose_name = "My Command"

    def ready(self):
        import my_command.commands.my_command

这样,我们就可以在命令行中执行我们自定义的my_command命令了。

示例一

下面给一个示例,对于所有存在过更新记录的表,在更新记录中添加一条新纪录。

  1. 在对应的app中创建management/commands文件夹。

  2. 创建名为update_all_tables.py的文件,定义更新数据的代码。

from django.core.management.base import BaseCommand
from app.models import *

class Command(BaseCommand):

    help = ("Add a new record to all tables which already have update records")

    def handle(self, *args, **options):
        for model in [table_model for table_model in (Table1, Table2, Table3)
                      if UpdateRecord.objects.filter(table_name=table_model.__name__).exists()]:
            last_update = model.update_records.last()
            model.update_records.create(updater="admin",
                                         update_time=datetime.datetime.now(),
                                         differences=None,
                                         record_after_changes=last_update.record_after_changes,
                                         note="Automatically added record by command update_all_tables")
  1. 在相应目录下执行python manage.py update_all_tables使用该扩展命令。

示例二

下面给另一个示例,向后台admin页面中添加一个命令,让用户可以在后台页面进行操作。

  1. app下创建一个名为admin.py的文件。
from django.contrib import admin
from django.urls import reverse
from django.utils.safestring import mark_safe
from django.http import HttpResponseRedirect
from django.urls import path, include
from django.conf import settings
from django.views.generic import TemplateView

from my_app.my_command import MyCommand

class ModelAdmin(admin.ModelAdmin):

    def get_urls(self):
        urls = super().get_urls()
        my_urls = [
            path('my_command/', self.admin_site.admin_view(self.my_view))
        ]
        return my_urls + urls

    def my_view(self, request):
        if request.method == 'POST':
            form = MyForm(request.POST)
            if form.is_valid():
                MyCommand().my_method(form.cleaned_data['name'], form.cleaned_data['text'])
                self.message_user(request, "Operation completed successfully.")
                return HttpResponseRedirect('../')
        else:
            form = MyForm()

        context = {
            'title': 'My Command',
            'form': form
        }

        return TemplateView.as_view(template_name='my_app/my_command_template.html')(request=request, context=context)

admin.site.register(MyModel, MyModelAdmin)
  1. 创建一个HTML模板my_command_template.html,用于后台页面,实现数据的录入。
{% extends 'admin/base_site.html' %}
{% load static %}

{% block extrahead %}
    {{ block.super }}
    <script type="text/javascript" src="{% static 'admin/js/vendor/jquery/jquery-3.4.1.min.js' %}"></script>
    <script type="text/javascript" src="{% static 'admin/js/jquery.init.js' %}"></script>
    <script type="text/javascript" src="{% static 'admin/js/actions.js' %}"></script>
{% endblock %}

{% block content %}
    <div class="container-fluid">
        <div class="row">
            <div class="col xs-12">
                <div class="submit-row">
                    <form method="POST">
                        {% csrf_token %}
                        <div class="form-group">
                            <label for="name">Name:</label>
                            <input type="text" class="form-control" id="name" name="name">
                        </div>
                        <div class="form-group">
                            <label for="text">Text:</label>
                            <textarea class="form-control" id="text" name="text" rows="3"></textarea>
                        </div>
                        <button type="submit" class="btn btn-primary">Submit</button>
                    </form>
                </div>
            </div>
        </div>
    </div>

    <script>
        window.addEventListener("load", function () {
            jQuery("#content-main").addClass("overflow-auto");
        });
    </script>

{% endblock %}
  1. 创建一个MyCommand类,用于后台数据处理。
class MyCommand(object):
    def my_method(self, name, text):
        # 处理数据的方法

以上就是如何使用Django实现自定义manage命令的扩展,并且以两个示例进行了说明。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:详解django实现自定义manage命令的扩展 - Python技术站

(0)
上一篇 2023年5月16日
下一篇 2023年5月16日

相关文章

  • [TimLinux] django 全局变量在WSGI多进程多线程环境中的研究

    场景1: 2个进程,每个进程1个线程,请求函数中设置了10秒sleep,9个请求同一URL: 结果: 1. 全局变量ID值,在每一个进程中相同,不同进程中不相同 2. 并行只能接受2个请求,同时发起多个请求,则需要排队等待处理   场景2: 1个进程,每个进程2个线程,请求函数中设置了10秒sleep,9个请求同一URL: 结果: 1. 全局变量ID值,在单…

    Django 2023年4月13日
    00
  • Django笔记二之连接数据库、执行migrate数据结构更改操作

    本篇笔记目录索引如下: Django 连接mysql,执行数据库表结构迁移步骤介绍 操作数据库,对数据进行简单操作 接下来几篇笔记都会介绍和数据库相关,包括数据库的连接、操作(包括增删改查)、对应的字段类型、model 里Meta 相关参数和 QueryAPI 的详解等。 这一篇先介绍数据库的连接和简单的增删改查操作。 首先介绍一些 Django 的操作表的…

    2023年4月10日
    00
  • SmartChart配合Django的安装与使用

    SmartChart的Git地址:https://gitee.com/smartchart/smartchart 在这里我只能说一句话 SmartChart开发团队真厉害 配合Django来使用SmartChart 安装smartchart,Python版本>=3.6,Django>=2.0SmartChart和我们的admin是有关联的,我们可…

    Django 2023年4月12日
    00
  • Django用户认证系统 User对象解析

    当我们在使用Django开发Web应用时,用户认证是非常常见的需求。Django提供了强大的用户认证系统来实现这一需求。其中,最核心的部分就是User对象。User对象是Django内置的代表用户身份和权限的模型。下面,我们来详细讲解Django用户认证系统User对象的相关知识。 User对象的组成 Django的User对象是由以下几个部分组成的: us…

    Django 2023年5月15日
    00
  • 对django中foreignkey的简单使用详解

    对Django中ForeignKey的简单使用详解 ForeignKey的作用 在Django的ORM中,ForeignKey是用来建立模型之间关系的一种字段类型。其作用是将一个模型与其他一个模型关联起来。 例如,在一个图书管理系统中,每一本书都是从一个出版社出版的,我们就可以在书的模型中使用ForeignKey关联出版社的模型。 ForeignKey的用法…

    Django 2023年5月16日
    00
  • Django之路由层的实现

    下面我将为你详细讲解“Django之路由层的实现”的完整攻略。 一、Django路由层简介 Django的路由层是Django框架中的一个重要组成部分,主要负责请求的分发和处理。通过路由,Django能够将一个请求(包括请求的URL和参数)分发给不同的视图(Views)进行处理,并将处理结果返回给客户端。在Django中,路由的实现机制是基于URL模式和视图…

    Django 2023年5月16日
    00
  • Django和Mezzanine初探

    Python框架中,Django是最著名的一个,Mezzanine是基于Django的一个框架。最初在决定学习Django的之后,先看了Django book一段时间,然后就开始四处寻找有价值的App,对我这个懒人来说,有App用,总比自己写要好。  后来看到了一个Mezzanine的介绍,将它比为Wordpress,wordpress是PHP的,而Mezz…

    Django 2023年4月11日
    00
  • django-pymysql-封装的sql使用

    封装的sql import pymysql def get_list(sql,args): conn = pymysql.connect(host=’127.0.0.1′, port=3306, user=’root’, passwd=”, db=’s4db65′, charset=’utf8′) cursor = conn.cursor(cursor=p…

    Django 2023年4月13日
    00
合作推广
合作推广
分享本页
返回顶部