下面我将详细讲解“详解django实现自定义manage命令的扩展”的完整攻略,过程中包含两条示例说明。
什么是manage.py命令
在Django中,我们一般使用manage.py
命令行工具来进行项目相关操作,例如启动服务器、创建数据库、添加管理员账户等等。
为什么需要自定义manage.py命令
虽然Django自带的manage.py命令已经非常丰富,但是有时候我们需要自己创建一些自定义的命令来解决项目中的特定问题,或者简化一些重复性的操作。这时候就需要我们自定义manage.py命令了。
如何实现自定义manage.py命令
要实现自定义manage.py命令,需要在Django项目中创建一个命令文件,然后在该文件中定义我们需要的命令。接下来分别讲解如何创建命令文件和如何定义自定义命令:
创建命令文件
先在Django项目的根目录下创建management
和commands
文件夹,然后在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
命令了。
示例一
下面给一个示例,对于所有存在过更新记录的表,在更新记录中添加一条新纪录。
-
在对应的
app
中创建management/commands
文件夹。 -
创建名为
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")
- 在相应目录下执行
python manage.py update_all_tables
使用该扩展命令。
示例二
下面给另一个示例,向后台admin
页面中添加一个命令,让用户可以在后台页面进行操作。
- 在
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)
- 创建一个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 %}
- 创建一个
MyCommand
类,用于后台数据处理。
class MyCommand(object):
def my_method(self, name, text):
# 处理数据的方法
以上就是如何使用Django实现自定义manage命令的扩展,并且以两个示例进行了说明。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:详解django实现自定义manage命令的扩展 - Python技术站