Django實戰1-許可權管理功能實現-12:選單URL新增實現
選單管理是用來管理系統中的URL資訊,將系統URL全部儲存到資料庫,繫結角色,透過角色組來控制系統導航選單的顯示和URL的訪問許可權。
為了讓大家能夠熟悉Django基於類檢視的使用,本節將透過ajax呼叫介面請求json資料的方式改為Django普通資料渲染的方式,同時將會使用到更多Django通用類檢視。
1 選單的新增檢視
1。1 普通實現
按照通常方法,我們先要在sandboxMP/apps/system/forms。py中新建MenuForm,用於對提交的資料進行驗證和儲存:
from 。models import Structure, Menu
class MenuForm(forms。ModelForm):
class Meta:
model = Menu
fields = ‘__all__’
然後在sandboxMP/apps/system/目錄下建立新的檔案views_menu。py,新增MenuCreateView:
import json
from django。views。generic。base import View
from django。shortcuts import render
from django。shortcuts import HttpResponse
from 。mixin import LoginRequiredMixin
from 。models import Menu
from 。forms import MenuForm
class MenuCreateView(LoginRequiredMixin, View):
def get(self, request):
ret = dict(menu_all=Menu。objects。all())
return render(request, ‘system/rbac/menu_create。html’, ret)
def post(self, request):
res = dict(result=False)
menu = Menu()
menu_form = MenuForm(request。POST, instance=menu)
if menu_form。is_valid():
menu_form。save()
res[‘result’] = True
return HttpResponse(json。dumps(res), content_type=‘application/json’)
最後配置URL和模板頁,選單的填加功能就完成了。
1。2 CreateView
1。1中是比較常用的新增檢視的寫法,接下來我們要在專案中使用CreateView來實現選單的新增檢視。在使用CreateView前先來了解下它的繼承關係、資料以及方法
1。2。1 CreateView的繼承關係
CreateView是透過多重繼承組成的新類,它的繼承關係如下圖所示(其中打勾的是前面已經學習並使用過的類):
1。2。2 CreateView繼承的屬性
1。2。3 CreateView繼承的方法
上面羅列出來的多重類繼承關係、屬性和方法,有空的時候建議看看原始碼,瞭解下具體實現和功能,梳理完CreateView的屬性和方法後我們就開始使用CreateView重寫MenuCreateView
1。3 使用CreateView實現選單新增功能
1、修改sandboxMP/apps/system/views_create。py 內容:
from django。views。generic import CreateView
from 。mixin import LoginRequiredMixin
from 。models import Menu
class MenuCreateView(LoginRequiredMixin, CreateView):
model = Menu
fields = ‘__all__’
success_url = ‘/system/rbac/menu/create’
這樣選單新增檢視就完成了,對比下1。1中的實現方式,程式碼精簡了許多,同時這裡也沒有使用自定義的form。
知識點介紹(知識點中涉及的方法和屬性,請對照前面統計表中內容,瞭解方法的繼承來源):
model:指定了模型:Menu
fields: 設定為all,將Menu模型所有欄位都對映到了ModelForm
success_url:定義資料新增成功後跳轉到的頁面
get_template_names(self):獲取模板資訊,如果沒有指定template_name,則會根據規則推斷出模板為:“system/menu_form。html”,其中system來自模型的應用程式名稱,menu是Memu模型的名稱小寫,_form是從template_name_suffix屬性中獲取的,當然我們也可以透過這個屬性指定自己想要的名稱,需要注意的是,在建立模板的時候一定要符合這個規則。
form_class:使用自定義form作為要例項化的form類,使用form_class時候,fields放在form類中定義,不可再放到檢視中定義
get_form_class: 檢索要例項化的表單類。 如果提供form_class,那麼將使用該類。 否則,將使用與queryset或model關聯的模型例項化ModelForm,上面程式碼中是透過Menu模型例項化的ModelForm
2、開啟sandboxMP/apps/system/urls。py,新增新的url配置:
urlpatterns = [
‘’‘原有內容省略’‘’
path(‘rbac/menu/create/’, views_menu。MenuCreateView。as_view(), name=‘rbac-menu-create’),
]
3、模板配置 新建 sandboxMP/templates/system/menu_form。html,內容如下:
{% extends “base-left。html” %}
{% load staticfiles %}
{% block css %}
{% endblock %}
{% block content %}
<!—— Main content ——>
<!—— /。content ——>
{% endblock %}
{% block javascripts %}
{% endblock %}
知識點介紹:
menu_form。html : 第11節中使用ListView的時候,沒有定義template_name,檢視根據規則自動生成了模板的路徑和名稱,這裡也是同樣的用法,按照一定的路徑和規則放置和定義模板,通用檢視會自動查詢模板並進行渲染。
{{ form。as_p }} : 使用django form進行前端表單資料的渲染(06:知識擴充套件-Django表單 一節已經介紹過這種用法)。
執行專案,訪問選單新增頁面,可以看到,透過Django form已經成功渲染了一個表單,按照圖中的內容,新增資料:
系統URL的配置請一定要跟著我的配置,不可隨意修改,不然後面渲染導航按鈕的時候就會出問題了。
儲存資料後,使用navicat連線資料庫,可以看到選單資料已經新增到資料庫system_menu表中:
1。4 選單新增功能的最佳化
現在使用的Django form渲染的新增表單,樣式比較醜陋,同時新增資料後還是跳轉到新增頁面,沒有提示資訊,接下來我們來最佳化下。
1。4。1 檢視的最佳化
我想資料新增成功後,不是跳轉頁面,而是將新增成功或失敗的結果序列化為Json格式返回,該怎麼辦呢?
答案是:我們可以重寫post()方法,當然,更深入一層,你也可以去重寫form_valid()方法。<
import json
from django。views。generic import CreateView
from django。shortcuts import HttpResponse
from 。mixin import LoginRequiredMixin
from 。models import Menu
class MenuCreateView(LoginRequiredMixin, CreateView):
model = Menu
fields = ‘__all__’
def post(self, request, *args, **kwargs):
res = dict(result=False)
form = self。get_form()
if form。is_valid():
form。save()
res[‘result’] = True
return HttpResponse(json。dumps(res), content_type=‘application/json’)
這樣就完成了檢視的修改,我們也可以把重寫的post方法單獨拿出來,作為擴充套件的通用類,這樣後面專案中所有需要新增資料的檢視都可以繼承我們自己擴充套件的通用類。
1。4。2 通用檢視的擴充套件
我們把具有共同特性的程式碼抽象出來,擴充套件通用檢視,達到可複用的目的,回顧專案前面幾節,組織架構的新增、使用者的新增。在專案中寫新增功能的時候我採用了兩種模式,一種是根據新增結果返回True或者False,前端根據結果提示 “新增成功”或者“新增失敗”,另一種是新增失敗時候,返回form表單中的自定義錯誤資訊,後面還會多次使用到新增檢視,這裡先把共性拿出來擴充套件通用檢視。
新建 sandboxMP/apps/custom。py,擴充套件的自定義檢視都放到這裡面,我們先寫第一個我們自定義擴充套件檢視:
import json
from django。views。generic import CreateView
from django。shortcuts import HttpResponse
from system。mixin import LoginRequiredMixin
class SimpleInfoCreateView(LoginRequiredMixin, CreateView):
def post(self, request, *args, **kwargs):
res = dict(result=False)
form = self。get_form()
if form。is_valid():
form。save()
res[‘result’] = True
return HttpResponse(json。dumps(res), content_type=‘application/json’)
刪除sandboxMP/apps/system/views_menu。py 裡面原有內容,替換成下面內容:
from apps。custom import SimpleInfoCreateView
from 。models import Menu
class MenuCreateView(SimpleInfoCreateView):
model = Menu
fields = ‘__all__’
是不是很簡單了,後面所有的只需要簡單返回True或False結果的新增檢視,都這麼寫就OK啦!
上面的檢視還需要稍作修飾,Menu模型中有一個外來鍵parent(父選單),我們在新增的時候希望能夠透過列表來選擇父選單,所有還需要傳遞額外的上下文,前面已經介紹過了,你是否已經掌握了呢?
from apps。custom import SimpleInfoCreateView
from 。models import Menu
class MenuCreateView(SimpleInfoCreateView):
model = Menu
fields = ‘__all__’
extra_context = dict(menu_all=Menu。objects。all())
這就是我們最終選單管理功能中的新增檢視啦。
1。4。3 模板的配置
接下來最佳化我們的模板配置吧,在模板中使用自定義的html form, 同時透過ajax提交資料到新增檢視,更具後端返回的狀態,提示相應的資訊。
開啟 sandboxMP/templates/system/menu_form。html,清空原有內容,新增如下內容:
{% extends ‘base-layer。html’ %}
{% load staticfiles %}
{% block css %}
<!—— iCheck for checkboxes and radio inputs ——>
{% endblock %}
{% block main %}
{% endblock %}
{% block javascripts %}
$(“#btnSave”)。click(function () {
var data = $(“#addForm”)。serialize();
$。ajax({
type: $(“#addForm”)。attr(‘method’),
url: “{% url ‘system:rbac-menu-create’ %}”,
data: data,
cache: false,
success: function (msg) {
if (msg。result) {
layer。alert(‘資料儲存成功!’, {icon: 1}, function (index) {
parent。layer。closeAll(); //關閉所有彈窗
});
} else {
layer。alert(‘資料儲存失敗’, {icon: 5});
//$(‘errorMessage’)。html(msg。message)
}
return;
}
});
});
/*點取消重新整理新頁面*/
$(“#btnCancel”)。click(function () {
window。location。reload();
});
$(function () {
//Initialize Select2 Elements
$(“。select2”)。select2();
});
{% endblock %}
執行專案,訪問選單新增頁面:
http://
127。0。0。1:8000/system/r
bac/menu/create/
, 效果如下:
經過測試,選單新增共功能可以正常使用,同時會返回提示資訊,至此選單管理中的新增功能已經完成,後面新增頁面會被作為彈窗呼叫。
最新最全文件,請關注我的知識星球:
https://
t。zsxq。com/a6IqBMr
(微信中開啟連結)
本節文件對應原始碼版本:
https://
github。com/RobbieHan/sa
ndboxMP/tree/v1。12
非常歡迎感興趣的朋友,到我的Github或知乎上做客,閒暇之餘給個贊或Star,贈人玫瑰手留餘香
文件配套專案地址:
https://
github。com/RobbieHan/sa
ndboxMP
知乎專欄SandBox:
https://
zhuanlan。zhihu。com/sand
box
輕量級辦公管理系統專案開源地址:
https://
github。com/RobbieHan/gi
standard