django admin是根据注册的模型来动态生成菜单,从这个思路出发,如果想添加自定义菜单,那就创建一个空模型并且注册。步骤如下:
1、创建空模型:
class ResetSVNAuthFileModel(models.Model):"""仅用来显示一个菜单"""class Meta:verbose_name = '重置授权文件'verbose_name_plural = verbose_name
2、注册到admin.py
重写changelist_view函数,使其点击菜单时,展示自定义的页面。在此你可以做orm查询,并且将数据渲染到模板中。而我想实现的是在页面中点击一个按钮来触发请求后端接口,来实现某种行为。
from django.contrib import admin
from django.shortcuts import renderfrom apps.setting.models import ResetSVNAuthFileModel@admin.register(ResetSVNAuthFileModel)
class FeedbackStatsAdmin(admin.ModelAdmin):def changelist_view(self, request, extra_content=None):template_name = 'reset_svn_auth_file.html'return render(request, template_name)
reset_svn_auth_file.html:
{% extends "admin/base_site.html" %}
{% load static %}{% block content %}<div class="text-center"><!-- 点击按钮调用 JavaScript 函数 --><button onclick="resetFunction()" id="resetButton" class="btn btn-primary btn-lg">重置授权文件</button></div>
{% endblock %}{% block extrahead %}<script src="https://cdn.jsdelivr.net/npm/sweetalert2@11"></script><script>function resetFunction() {// 禁用按钮document.getElementById("resetButton").disabled = true;// 发送 AJAX 请求到 Django 视图fetch('/admin-api/reset-auth-file').then(response => {if (response.ok) {Swal.fire({icon: 'success',title: 'OK',text: '操作成功',})} else {response.json().then(data => {console.log(data)Swal.fire({icon: 'error',title: '重置失败',text: data.msg,})})}}).catch((error) => {Swal.fire({icon: 'error',title: 'Oops...',text: '请求失败',})}).finally(() => {// 恢复按钮状态document.getElementById("resetButton").disabled = false;});}</script>
{% endblock %}
把该文件放在空模型所在app下的templates文件夹。
3、定义后端路由和接口
django总路由:
from django.contrib import admin
from django.urls import path, includefrom apps.repository.views import ResetAuthFileViewadmin_api = [path('reset-auth-file/', ResetAuthFileView.as_view(), name='reset-auth-file'),]urlpatterns = [path('admin/', admin.site.urls),path('admin-api/', include(admin_api)), # 在admin 自定义页面中发送过来的请求
]
接口函数:
class ResetAuthFileView(APIView):def get(self, request):# 可以写个中间件做认证sessionid = request.COOKIES.get('sessionid')csrftoken = request.COOKIES.get('csrftoken')session = SessionStore(session_key=sessionid)if not session.exists(session_key=sessionid):return Response(status=401)try:SVN.reset_authz_file()except Exception as e:return Response(data={'msg': f'重置失败:{e}'}, status=400)return Response(data={'msg': '重置完成'})
大功告成,看成果:
点击菜单后的页面: