实现option上下移动_Django实战2-自动化运维之配置管理-05:字典管理功能实现
1、字典管理頁面實現
首先來實現字段管理的基礎管理頁面,針對字典的一系列操作,都將在這個頁面上完成。
1.1 字典管理視圖實現
新建sandboxMP/apps/cmdb/views_code.py,寫入如下內容:
from django.views.generic import TemplateViewfrom system.mixin import LoginRequiredMixin from custom import BreadcrumbMixin from .models import Codeclass CodeView(LoginRequiredMixin, BreadcrumbMixin, TemplateView):template_name = 'cmdb/code.html'def get_context_data(self):self.kwargs['code_parent'] = Code.objects.filter(parent=None)return super().get_context_data(**self.kwargs)在上面視圖中,通過重寫get_context_data方法來返回字典數據中所有父類為None的上下文,用來作為過濾查詢時的選擇項。
1.2 字典管理訪問URL
打開,sandboxMP/apps/cmdb/urls.py,添加如下內容:
from . import views_codeurlpatterns = ['''原有內容省略'''path('portal/code/', views_code.CodeView.as_view(), name='portal-code'), ]根據權限管理中URL定義規則,這里將字段管理功能URL放到portal分組中;在實戰2第三節中已經說明,新的URL都需要添加到權限系統。
1.3 字典管理模板配置
修建模板文件:sandboxMP/templates/cmdb/code.html,內容如下:
{% extends "base-left.html" %} {% load staticfiles %}{% block css %}<link rel="stylesheet" href="{% static 'plugins/datatables/jquery.dataTables.min.css' %}"><link rel="stylesheet" href="{% static 'js/plugins/layer/skin/layer.css' %}"><link rel="stylesheet" href="{% static 'plugins/select2/select2.min.css' %}"> {% endblock %}{% block content %}<!-- Main content --><section class="content"><div id="devlist"><div class="box box-primary" id="liebiao"><div class="box-header"><div class="btn-group pull-left"><button type="button" id="btnRefresh" class="btn btn-default"><i class="glyphicon glyphicon-repeat"></i>刷新</button></div><div class="btn-group pull-left"> </div><div class="btn-group pull-left"><button type="button" id="btnCreate" class="btn btn-default"><i class="glyphicon glyphicon-plus"></i>新增</button></div><div class="btn-group pull-left"> </div><div class="btn-group pull-left"><button type="button" id="btnDelete" class="btn btn-default"><i class="glyphicon glyphicon-trash"></i>刪除</button></div><div class="pull-right"><form class="form-inline" id="queryForm"><div class="form-group searchArea margin-r-5 margin-top-5"><label>字典分類:</label><select class="form-control inputText select2" name="parent" id="parent"><option style='text-align:center' value="">---所有---</option>{% for code in code_parent %}<option value={{ code.key}}>{{ code.value }}</option>{% endfor %}</select></div></form></div></div><div class="box-body"><table id="dtbList" class="display" cellspacing="0" width="100%"><thead><tr valign="middle"><th><input type="checkbox" id="checkAll"></th><th>ID</th><th>KEY</th><th>VALUE</th><th>所屬</th><th>操作</th></tr></thead><tbody></tbody></table><br> <br></div></div></div></section><!-- /.content -->{% endblock %}{% block javascripts %}<script src="{% static 'plugins/datatables/jquery.dataTables.min.js' %}"></script> <script src="{% static 'plugins/datatables/dataTables.const-1.js' %}"></script> <script src="{% static 'js/plugins/layer/layer.js' %}"></script> <script src="{% static 'plugins/select2/select2.full.min.js' %}"></script>{% endblock %}==按下CRTL + S 保存并上傳項目文件==
1.4 權限管理配置
URL數據內容:
運行項目,登陸系統,訪問菜單管理頁【系統】→ 【權限管理】→ 【菜單管理】,按照上面URL內容,將數據添加到菜單管理中:
http://172.16.3.100:8000/system/rbac/menu/訪問角色管理頁【系統】→ 【權限管理】→ 【角色管理】,選擇【系統管理】后面第三個樹形按鈕配置權限信息,將新配置的URL授權給角色組:系統管理,選擇好菜單后(全選)點【生成】按鈕。
http://172.16.3.100:8000/system/rbac/role/完成權限配置就可以在頁面中訪問【配置管理】→ 【平臺設置】→ 【字典管理】。
每一個視圖功能的訪問都需要做對應的權限配置,在后面不再列出添加和授權步驟。
2 字典添加功能實現
2.1 字典添加Form配置
打開文件:sandboxMP/apps/cmdb/forms.py,寫入如下內容:
from django import formsfrom .models import Codeclass CodeCreateForm(forms.ModelForm):class Meta:model = Codefields = '__all__'error_messages = {'key': {'required': 'key不能為空'},'value': {'required': 'value不能為空'}}def clean(self):cleaned_data = super(CodeCreateForm, self).clean()key = cleaned_data.get('key')value = cleaned_data.get('value')if Code.objects.filter(key=key).count():raise forms.ValidationError('key:{}已存在'.format(key))if Code.objects.filter(value=value).count():raise forms.ValidationError('value: {}已存在'.format(value))通過CodeCreateForm可以對輸入數據的有效性進行驗證,同時避免內容重復。
CTRL + S 保存并上傳。
2.2 字典添加視圖實現
打開:sandboxMP/apps/cmdb/views_code.py,添加CodeCreateView視圖:
from custom import SandboxCreateView from .forms import CodeCreateFormclass CodeCreateView(SandboxCreateView):model = Codeform_class = CodeCreateFormtemplate_name_suffix = '_create'def get_context_data(self, **kwargs):kwargs['code_parent'] = Code.objects.filter(parent=None)return super().get_context_data(**kwargs)字典添加視圖,使用了在django實戰1中創建的SandboxCreateView,重寫get_context_data 返回所有父類code,用于創建時候的選擇項。
SandboxCreateView類當初在定義的時候,只返回了執行結果result(True or False),前端根據result結果來提示執行成果或執行失敗,這里想要返回form中自定義的錯誤提示信息,修改sandboxMP/apps/custom.py中SandboxEditViewMixin,內容如下:
2.4 字典添加URL配置
打開:sandboxMP/apps/cmdb/urls.py,添加新的URL:
urlpatterns = ['''原有內容省略'''path('portal/code/create/', views_code.CodeCreateView.as_view(), name='portal-code-create'), ]2.5 模板配置
新建模板文件:sandboxMP/templates/cmdb/code_crate.html,內容如下:
{% extends 'base-layer.html' %} {% load staticfiles %} {% block css %}<link rel="stylesheet" href="{% static 'plugins/select2/select2.min.css' %}"><!-- iCheck for checkboxes and radio inputs --> {% endblock %} {% block main %}<div class="box box-danger"><form class="form-horizontal" id="addForm" method="post">{% csrf_token %}<div class="box-body"><fieldset><legend><h4>新建字典</h4></legend><div class="form-group has-feedback"><label class="col-sm-2 control-label">KEY</label><div class="col-sm-3"><input class="form-control" name="key" type="text"/></div><label class="col-sm-2 control-label">VALUE</label><div class="col-sm-3"><input class="form-control" name="value" type="text" /></div></div><div class="form-group has-feedback"><label class="col-sm-2 control-label">父菜單</label><div class="col-sm-3"><select class="form-control select2" name="parent"><option value=""></option>{% for parent in code_all %}<option value={{ parent.id }}> {{ parent.value }} </option>{% endfor %}</select></div><label class="col-sm-2 control-label">描述信息</label><div class="col-sm-3"><input class="form-control" id="desc" name="desc" type="text" /></div></div></fieldset></div><div class="box-footer "><div class="row span7 text-center "><button type="button" id="btnCancel" class="btn btn-default margin-right ">重置</button><button type="button" id="btnSave" class="btn btn-info margin-right ">保存</button></div></div></form></div>{% endblock %}{% block javascripts %}<script src="{% static 'plugins/select2/select2.full.min.js' %}"></script><script type="text/javascript">$("#btnSave").click(function () {var data = $("#addForm").serialize();$.ajax({type: $("#addForm").attr('method'),url: "{% url 'cmdb:portal-code-create' %}",data: data,cache: false,success: function (msg) {if (msg.result) {layer.alert('數據保存成功!', {icon: 1}, function (index) {parent.layer.closeAll(); //關閉所有彈窗});} else {layer.alert(msg.error, {icon: 5});//$('errorMessage').html(msg.message)}return;}});});/*點取消刷新新頁面*/$("#btnCancel").click(function () {window.location.reload();});$(function () {//Initialize Select2 Elements$(".select2").select2();});</script>{% endblock %}注意:在{% block javascripts %}標簽中的$("#btnSave")方法在執行成功后,提示信息中通過msg.error來返回form中的錯誤提示信息。
給字典管理頁 添加按鈕綁定添加事件,打開sandboxMP/templates/cmdb/code.html,在{% block javascripts %}中的菜單高亮代碼段后面添加如下代碼:
2.6 權限管理配置
請將下面URL數據添加到菜單管理,并授權給【系統管理】角色組:
菜單添加和角色授權過程不再單獨寫出來了,前面內容已經介紹夠了。
配置完授權后就可以通過字典管理頁面中的添加按鈕來添加新的字典數據:
http://172.16.3.100:8000/cmdb/portal/code/3 字典數據列表展示
在django實戰1中,我們使用datatables通過ajax來獲取并展示數據信息,數據分頁是使用的datatables的前端分頁,本節將介紹使用datatables的后端分頁功能。
3.1 自定義數據列表類
創建一個帶有分頁和過濾查詢的數據列表Mixin類,可用于所有基于datatables后端分頁的數據,打開sandbox/apps/custom.py,添加如下內容:
from django.views.generic import View from django.http import JsonResponse from django.db.models.query import QuerySet from django.core.exceptions import ImproperlyConfiguredclass SandboxMultipleObjectMixin:filters = {}fields = []queryset = Nonemodel = None# 用來獲取queryset,下面內容參照了Django通用類視圖的基本寫法def get_queryset(self):if self.queryset is not None:queryset = self.querysetif isinstance(queryset, QuerySet):queryset = queryset.all()elif self.model is not None:queryset = self.model._default_manager.all()else:raise ImproperlyConfigured("%(cls)s is missing a QuerySet. Define ""%(cls)s.model, %(cls)s.queryset."% {'cls': self.__class__.__name__})return querysetdef get_datatables_paginator(self, request):# 從request中獲取datatables需要服務端處理的數據信息,具體內容參照下面知識點介紹datatables = request.GETdraw = int(datatables.get('draw'))start = int(datatables.get('start'))length = int(datatables.get('length'))order_column = datatables.get('order[0][column]')order_dir = datatables.get('order[0][dir]')order_field = datatables.get('columns[{}][data]'.format(order_column))# 使用self.get_queryset方法來獲取queryset數據queryset = self.get_queryset()# 根據datatables傳遞回來的排序信息進行排序(支持正向和反向排序)if order_dir == 'asc':queryset = queryset.order_by(order_field)else:queryset = queryset.order_by('-{0}'.format(order_field))# 統計所有數據條目record_total_count = queryset.count()# 獲取過濾字段filters = self.get_filters()# 獲取需要在datatables中展示的字段fields = self.get_fields()if filters:queryset = queryset.filter(**filters)if fields:queryset = queryset.values(*fields)# 過濾后的數據條目record_filter_count = queryset.count()# 對queryset進行切片操作,只返回當前需要展示的數據object_list = queryset[start:(start + length)]data = list(object_list)# 下面內容是datatables后端分頁必須返回的數據,網上有些說明return {'draw': draw,'recordsTotal': record_total_count,'recordsFiltered': record_filter_count,'data': data,}def get_filters(self):return self.filtersdef get_fields(self):return self.fieldsclass SandboxListView(LoginRequiredMixin, SandboxMultipleObjectMixin, View):"""JsonResponse some json of objects, set by `self.model` or `self.queryset`."""def get(self, request):context = self.get_datatables_paginator(request)return JsonResponse(context)知識點介紹(查看代碼中注釋部分):
1、datatables 后端分頁的請求參數和返回參數詳情可以查看下面內容:
2、JsonResponse(context) 接受字典數據,實現了json.dumps()和 HttpResponse兩個功能,對比下SandboxEditViewMixin。
3.2 字典列表視圖實現
打開sandboxMP/apps/cmdb/views_code.py,添加CodeListView:
from custom import SandboxListViewclass CodeListView(SandboxListView):model = Codefields = ['id', 'key', 'value', 'parent__value']def get(self, request):if 'parent' in request.GET and request.GET['parent']:self.filters = dict(parent__key=request.GET['parent'])return super().get(request)知識點介紹:
1、CodeListView繼承了SandboxListView,通過fields指定需要在列表中展示的字段,其中parent是一個外鍵,通過parent__value實現多級的取值。
2、重寫get方法,從request中獲取parent(前端頁面中傳遞的是parent的key)內容,將數據組合成字典賦值給filters,后端會根據filters內容進行數據的過濾。
3.3 字典列表URL
打開sandboxMP/apps/cmdb/urls.py,添加如下內容:
from . import views_codeurlpatterns = ['''原有內容省略'''path('portal/code/list/', views_code.CodeListView.as_view(), name='portal-code-list'), ]3.4 模板配置
打開sandboxMP/templates/cmdb/code.html,在{% block javascripts %}下菜單高亮代碼段后面添加datatables初始化配置和數據過濾刷新ajax請求的代碼段:
// datatables 初始化配置var oDataTable = null;$(function () {oDataTable = initTable();function initTable() {var oTable = $('#dtbList').DataTable($.extend(true, {},DATATABLES_CONSTANT.DATA_TABLES.SERVER_SIDE_OPTION,{ajax: {"url": "{% url 'cmdb:portal-code-list' %}","data": function (d) {d.parent = $("#parent").val();}},columns: [DATATABLES_CONSTANT.DATA_TABLES.COLUMN.CHECKBOX,{data: "id",width: "5%",},{data: "key",//width : "20%",},{data: "value",//width : "20%",},{data: "parent__value",//width : "20%",},{data: "id",width: "10%",bSortable: "false",render: function (data, type, row, meta) {var ret = "";var ret = "<button title='詳情' onclick='doUpdate("+ data + ")'><i class='glyphicon glyphicon-pencil'></i></button>";ret = ret + "<button title='刪除' onclick='doDelete("+ data + ")'><i class='glyphicon glyphicon-trash'></i></button>";return ret;}}],}));return oTable;}});//select2$(function () {//Initialize Select2 Elements$(".select2").select2();});//過濾刷新接口獲取新的數據$("#parent").change(function () {oDataTable.ajax.reload();});打開sandboxMP/static/plugins/datatables/dataTables.const-1.js,修改下面注釋部分內容,把DEFAULT_OPTION 改成 SERVER_SIDE_OPTION
var DATATABLES_CONSTANT = { // datatables常量 DATA_TABLES : { SERVER_SIDE_OPTION : { // 把DEFAULT_OPTION改成SERVER_SIDE_OPTIONoLanguage : { sProcessing : "處理中...", sLengthMenu : "每頁 _MENU_ 項",//"顯示 _MENU_ 項結果,", sZeroRecords : "沒有匹配結果", sInfo : "顯示第 _START_ 至 _END_ 項結果(共 _TOTAL_ 項)",'''原有內容省略'''系統中啟用了后端分頁,所以在初始化datatables表格的時候,使用的是daTables.const-1.js,這個文件中配置了后端分頁的一些基本配置,上面代碼中注釋部分修改的名稱只是為了卻分前端分頁的配置內容,同時在code.html初始化datatables的時候調取的是SERVER_SIDE_OPTION。
CRTL + S 保存并上傳。
3.5 權限管理配置
請將下面URL數據添加到菜單管理,并授權給【系統管理】角色組:
3.6 后端分頁功能測試
到這里后端分頁和過濾功能已經完整實現了,將下面的字典數據添加到系統,驗證各個功能:
運行項目,訪問系統字典管理頁,通過新增按鈕完成上面字典數據的添加工作:
http://172.16.3.100:8000/cmdb/portal/code/CTRL + F5 刷新頁面,在頁面中可以看到數據已經自動完成分頁,我們和可以設置每頁顯示的數據條目,可以切換分頁獲取不同數據,可以通過字典分類進行數據過濾,可以點擊表格頭部進行數據排序。
3.6 datatables后端分頁參數梳理方法
在使用datatables后端分頁功能后,很多人面對一堆參數和后端的代碼處理邏輯時會有點懵,先瀏覽一遍上面給的后端分頁參數網址,了解參數的基本用途,然后使用Chrome瀏覽器訪問字典管理頁面,按F12打開瀏覽器調試窗口,F5刷新頁面,選擇Chrome調試窗口中的 Network → ?draw=... → Headers 往下拖在后面可以看到datatables傳遞給后臺的參數。
對照自定義的SandboxMultipleObjectMixin中get_datatables_paginator(self, request)方法中通過request中獲取的datattables分頁參數,理解參數的具體意義。
也可以切換分頁后查看chrome調試敞口中最新訪問的?draw=..Headers中start參數的變化。
選擇每頁顯示數據條目,對比下chrome調試敞口中最新訪問的?draw=..Headers中length參數的變化。
點擊表格頭部KEY進行排序,查看chrome調試敞口中最新訪問的?draw=..Headers中order[0][column],order[0][dir],columns[2][data]內容,然后再去理解下get_datatables_paginator(self, request)方法中獲取參數的內容。
一定要去做下操作,然后在對比下參數,和后端代碼中實現,才能夠加深理解。
4 字典更新功能實現
4.1 字典更新Form驗證
打開文件:sandboxMP/apps/cmdb/forms.py,添加如下內容:
class CodeUpdateForm(CodeCreateForm):def clean(self):cleaned_data = self.cleaned_datakey = cleaned_data.get('key')value = cleaned_data.get('value')if self.instance:matching_code = Code.objects.exclude(pk=self.instance.pk)if matching_code.filter(key=key).exists():msg = 'key:{} 已經存在'.format(key)raise forms.ValidationError(msg)if matching_code.filter(value=value).exists():msg = 'value:{} 已經存在'.format(value)raise forms.ValidationError(msg)在更新字典數據的時候,同樣需要驗證輸入字段的有效性,這點在CodeCreateForm中已經時間了,避免代碼重復,這里直接繼承CodeCreateForm。同時重寫clean方法,排除當前修改的數據之外保證數據沒有重復。
4.2 字典更新視圖
字典更新視圖可以使用SandboxUpdateView來實現,打開sandboxMP/apps/cmdb/views_code.py,添加CodeUpdateView:
from custom import SandboxUpdateView from .forms import CodeUpdateFormclass CodeUpdateView(SandboxUpdateView):model = Codeform_class = CodeUpdateFormtemplate_name_suffix = '_update'def get_context_data(self, **kwargs):kwargs['code_parent'] = Code.objects.filter(parent=None)return super().get_context_data(**kwargs)4.3 字典更新URL
打開sandboxMP/apps/cmdb/urls.py,添加新的url:
urlpatterns = ['''原有內容省略'''path('portal/code/update/', views_code.CodeUpdateView.as_view(), name='portal-code-update'),4.4 模板配置
新建模板sandboxMP/templates/cmdb/code_update.html:
{% extends 'base-layer.html' %} {% load staticfiles %} {% block css %}<link rel="stylesheet" href="{% static 'plugins/select2/select2.min.css' %}"><!-- iCheck for checkboxes and radio inputs --> {% endblock %} {% block main %}<div class="box box-danger"><form class="form-horizontal" id="addForm" method="post"><input type="hidden" name='id' type='text' value="{{ code.id }}"/>{% csrf_token %}<div class="box-body"><fieldset><legend><h4>修改字典</h4></legend><div class="form-group has-feedback"><label class="col-sm-2 control-label">KEY</label><div class="col-sm-3"><input class="form-control" name="key" type="text" value="{{ code.key }}"/></div><label class="col-sm-2 control-label">VALUE</label><div class="col-sm-3"><input class="form-control" name="value" type="text" value="{{ code.value }}"/></div></div><div class="form-group has-feedback"><label class="col-sm-2 control-label">父菜單</label><div class="col-sm-3"><select class="form-control select2" name="parent"><option value={{ code.parent.id }}> {{ code.parent.value }} </option><option value=""></option>{% for parent in code_parent %}<option value={{ parent.id }}> {{ parent.value }} </option>{% endfor %}</select></div><label class="col-sm-2 control-label">描述信息</label><div class="col-sm-3"><input class="form-control" id="desc" name="desc" type="text" value="{{ code.desc }}"/></div></div></fieldset></div><div class="box-footer "><div class="row span7 text-center "><button type="button" id="btnCancel" class="btn btn-default margin-right ">重置</button><button type="button" id="btnSave" class="btn btn-info margin-right ">保存</button></div></div></form></div>{% endblock %}{% block javascripts %}<script src="{% static 'plugins/select2/select2.full.min.js' %}"></script><script type="text/javascript">$("#btnSave").click(function () {var data = $("#addForm").serialize();$.ajax({type: $("#addForm").attr('method'),url: "{% url 'cmdb:portal-code-update' %}",data: data,cache: false,success: function (msg) {if (msg.result) {layer.alert('數據保存成功!', {icon: 1}, function (index) {parent.layer.closeAll(); //關閉所有彈窗});} else {layer.alert(msg.error, {icon: 5});//$('errorMessage').html(msg.message)}return;}});});/*點取消刷新新頁面*/$("#btnCancel").click(function () {window.location.reload();});$(function () {//Initialize Select2 Elements$(".select2").select2();});</script>{% endblock %}打開sandboxMP/templates/cmdb/code.html,給修改綁定事件,在{% block javascripts %}中新建字典$("#btnCreate")的代碼段后面添加如下內容:
//修改字典 function doUpdate(id) {layer.open({type: 2,title: '編輯',shadeClose: false,maxmin: true,area: ['800px', '400px'],content: ["{% url 'cmdb:portal-code-update' %}" + '?id=' + id, 'no'],end: function () {oDataTable.ajax.reload();}}); }CTRL + S 保存并上傳。
4.5 權限管理配置
請將下面URL數據添加到菜單管理,并授權給【系統管理】角色組:
運行項目測試字典修改功能。
5 字典刪除功能實現
5.1 字典刪除視圖
回顧下用戶管理、組織組織架構管理、菜單管理、角色管理這些功能中的刪除視圖的實現,盡管刪除視圖的實現在代碼上已經算得上是很精簡了,但是這些刪除視圖代碼基本一致,所以也可以抽象出來寫成自定義類。
打開sandboxMP/apps/custom.py,添加如下內容:
打開sandboxMP/apps/cmdb/views_code.py,添加刪除視圖:
from custom import SandboxDeleteViewclass CodeDeleteView(SandboxDeleteView):model = Code5.2 字典刪除URL
打開sandboxMP/apps/cmdb/urls.py,添加新的URL:
urlpatterns = ['''原有內容省略'''path('portal/code/delete/', views_code.CodeDeleteView.as_view(), name='portal-code-delete'),]5.3 模板配置
給刪除按鈕綁定刪除事件,打開sandboxMP/templates/cmdb/code.html,在{% block javascripts %}標簽中修改字典doUpdate()代碼段后面添加如下內容:
//checkbox全選$("#checkAll").on("click", function () {if ($(this).prop("checked") === true) {$("input[name='checkList']").prop("checked", $(this).prop("checked"));$('#example tbody tr').addClass('selected');} else {$("input[name='checkList']").prop("checked", false);$('#example tbody tr').removeClass('selected');}});//批量刪除$("#btnDelete").click(function () {if ($("input[name='checkList']:checked").length == 0) {layer.msg("請選擇要刪除的記錄");return;}var arrId = new Array();$("input[name='checkList']:checked").each(function () {//alert($(this).val());arrId.push($(this).val());});sId = arrId.join(',');layer.alert('確定刪除嗎?', {title: '提示', icon: 3 //0:感嘆號 1:對號 2:差號 3:問號 4:小鎖 5:哭臉 6:笑臉, time: 0 //不自動關閉, btn: ['YES', 'NO'], yes: function (index) {layer.close(index);$.ajax({type: "POST",url: "{% url 'cmdb:portal-code-delete' %}",data: {"id": sId, csrfmiddlewaretoken: '{{ csrf_token }}'},cache: false,success: function (msg) {if (msg.result) {layer.alert("操作成功", {icon: 1});oDataTable.ajax.reload();} else {//alert(msg.message);layer.alert("操作失敗", {icon: 2});}return;}});}});});//刪除單個數據function doDelete(id) {layer.alert('確定刪除嗎?', {title: '提示', icon: 3 //0:感嘆號 1:對號 2:差號 3:問號 4:小鎖 5:哭臉 6:笑臉, time: 0 //不自動關閉, btn: ['YES', 'NO'], yes: function (index) {layer.close(index);$.ajax({type: "POST",url: "{% url 'cmdb:portal-code-delete' %}",data: {"id": id, csrfmiddlewaretoken: '{{ csrf_token }}'},cache: false,success: function (msg) {if (msg.result) {layer.alert('刪除成功', {icon: 1});oDataTable.ajax.reload();} else {//alert(msg.message);layer.alert('刪除失敗', {icon: 2});}return;}});}});}CTRL + S 保存并上傳
5.4 權限管理配置
請將下面URL數據添加到菜單管理,并授權給【系統管理】角色組:
運行項目測試批量刪除和單條刪除功能。
至此,項目中已經完成新增、修改、列表、刪除的自定義功能,這些類在項目中有相同需求時都可以直接繼承使用。
作業:了解YAML語法格式,以及通過python來讀取和寫入YAML文件
最新最全文檔,請關注我的知識星球: https://t.zsxq.com/MBiqJi2(微信中打開鏈接)本節文檔對應源碼版本: https://github.com/RobbieHan/sandboxMP/tree/v2.05
輕量級辦公管理系統項目開源地址:https://github.com/RobbieHan/gistandard
總結
以上是生活随笔為你收集整理的实现option上下移动_Django实战2-自动化运维之配置管理-05:字典管理功能实现的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: ajax结构图,Vuex结构图及用法
- 下一篇: python3实用编程技巧_6.pyth