Django基于Admin原理實現(xiàn)的CURD組件
Django管理后臺admin
常用共29個功能: 參考
- 在項目的app中的admin.py文件中注冊models類晌该,示例如下:
# cat app_name/admin.py
from django.contrib import admin
from django.contrib.admin import ModelAdmin
from . import models
from django.shortcuts import HttpResponse
from django.forms import ModelForm
from django.forms import fields
from django.forms import widgets
# 用戶表,自定義admin后臺錯誤信息提示
class UserModelForm(ModelForm):
others = fields.CharField()
class Meta:
model = models.UserInfo
fields = "__all__"
error_messages = {
'name':{'required':'用戶名不能問空'}
}
class UserInfoModelAdmin(ModelAdmin):
# 使用自定義的form表單驗證功能
form = UserModelForm
# 1.定義列表頁面,顯示列數(shù)據(jù)
list_display = ['name','pwd','email']
def email(self, obj):
return obj.name + obj.pwd
email.empty_value_display = "默認(rèn)為空時顯示的值"
# 2.定義列表頁面,列可以進(jìn)行點擊進(jìn)入編輯頁面
list_display_links = ['pwd']
# 3.定義列表頁面商蕴,快速搜索
list_filter = ['ut']
# 4.定義列表頁面,分頁功能
list_per_page = 10
# 5. 列是否可編輯
list_editable = ['name']
# 6. 查詢列
search_fields = ['name','pwd']
# 7. 是否在頁面頂端顯示保存按鈕
# save_on_top = True
# 8. 下拉選項的批量操作夭禽,類似于批量刪除功能
def func(self, request, queryset):
print(self, request, queryset)
id_list = request.POST.getlist('_selected_action')
# models.UserInfo.objects.filter(id__in=id_list).delete()
func.short_description = "批量初始化"
actions = [func, ]
# 9. 列表頁面使用模板文件
change_list_template = ['xxx.html']
# raw_id_fields = ['ut',]
# fields = ['name']
# exclude = ['name',]
# 10. 分類展示
# fieldsets = (
# ('基本數(shù)據(jù)', {
# 'fields': ('name',)
# }),
# ('其他', {
# 'classes': ('collapse', 'wide', 'extrapretty'), # 'collapse','wide', 'extrapretty'
# 'fields': ('pwd', 'ut'),
# }),
# )
# 11.快速過濾
# filter_vertical = ("roles",)
filter_horizontal = ("roles",)
# 12. 排序
ordering = ['-id']
# 注冊使用自定義的UserInfoModelAdmin類的頁面展示規(guī)則
admin.site.register(models.UserInfo,UserInfoModelAdmin)
# 2. 用戶類型表(基于ModelAdmin類)
class UserTypeModelAdmin(ModelAdmin):
list_display = ['title']
admin.site.register(models.UserType,UserTypeModelAdmin)
注: 默認(rèn)使用ModelAdmin類進(jìn)行后臺操作或颊,可以定義自己的calss砸紊,通過繼承ModelAdmin類實現(xiàn)定制頁面展示功能
- Django自帶Admin原理
2.1 每注冊一個model類,Django內(nèi)部會生成4個對應(yīng)的增刪改查URL囱挑,如下所示:
URL:
/admin/app_name/model_name/
/admin/app_name/model_name/add/
/admin/app_name/model_name/1/change/
/admin/app_name/model_name/1/delete/
例:/admin/app01/userinfo/
2.2 內(nèi)部實現(xiàn)機(jī)制
- 在app下面的admin.py文件中注冊models類;
- Django程序在啟動時會循環(huán)所有app下面的admin文件中注冊的models類醉顽,為每個models類生成對應(yīng)的增刪改查4個URL;
- 每個注冊的model類會封裝一個用于處理當(dāng)前類所對應(yīng)的URL的view對象,用于處理CURD操作,默認(rèn)為ModelAdmin類對象;
1. self.model=models.UserInfo
/admin/app01/userinfo/ obj1.changelist_view
/admin/app01/userinfo/add/ obj1.add_view
/admin/app01/userinfo/(\d+)/delete/ obj1.delete_view
/admin/app01/userinfo/(\d+)/change/ obj1.change_view
2. self.model=models.UserType
/admin/app01/usertype/ obj2.changelist_view
/admin/app01/usertype/add/ obj2.add_view
/admin/app01/usertype/(\d+)/delete/ obj2.delete_view
/admin/app01/usertype/(\d+)/change/ obj2.change_view
</br>
自定義實現(xiàn)CURD類似Admin功能
步驟
- 了解django啟動時執(zhí)行的啟動文件順序
- 制作啟動文件
- settings.py配置文件中注冊啟動文件使全局生效
- 實現(xiàn)組件CURD業(yè)務(wù)邏輯
- 主要參考Django Admin的實現(xiàn)平挑,利用單利模式和include原理實現(xiàn)路由分發(fā)
實現(xiàn)
假設(shè)組件app名稱為: arya
- Django程序啟動順序
在程序啟動時游添,django會根據(jù)配置項INSTALLED_APPS中注冊的啟動文件,遍歷每個App下面對應(yīng)的注冊啟動文件,在arya組件下面的app.py文件中實現(xiàn)ready方法激活啟動文件,如下:
# arya/app.py
from django.apps import AppConfig
class AryaConfig(AppConfig):
name = 'arya'
# Django啟動時自動掃描所有app下面的arya模塊
def ready(self):
from django.utils.module_loading import autodiscover_modules
autodiscover_modules('arya')
- 在項目的setting.py文件中配置通熄,激活組件否淤,使全局生效,此時Django啟動時棠隐,在完全啟動前,便會掃描所有app下面的arya.py文件并加載生效
INSTALLED_APPS = [
...
'arya.apps.AryaConfig',
...
]
- 核心代碼邏輯實現(xiàn)
# cat arya/seevice/v1.py
from django.conf.urls import url
from django.shortcuts import render, HttpResponse, redirect
class AryaConfig(object):
"""
每個models類的URL對應(yīng)處理的View實現(xiàn)
"""
def __init__(self, model_class, site):
self.model_class = model_class
# View對象
self.site = site
@property
def urls(self):
partterns = [
url(r'^$', self.changelist_view),
url(r'^add/', self.add_view),
url(r'^(\d+)/change/$', self.change_view),
url(r'^(\d+)/delete/$', self.delete_view)
]
return partterns
def changelist_view(self, request):
"""
列表試圖
:param request:
:return:
"""
# return HttpResponse("列表頁面")
return render(request, 'arya/changelist.html')
def add_view(self, request):
"""
添加試圖
:param request:
:return:
"""
return HttpResponse("添加試圖")
def change_view(self, request):
"""
修改試圖
:param request:
:return:
"""
return HttpResponse("修改試圖")
def delete_view(self, request):
"""
刪除試圖
:param request:
:return:
"""
return HttpResponse("刪除試圖")
class AryaSite(object):
"""
實現(xiàn)類似于admin.site.register()功能
"""
# 存放所有的models類及對應(yīng)處理UTRL的的view對象
def __init__(self):
self._registry = {}
def register(self, class_name, config_class):
"""
注冊方法,封裝對象
self._registry = {
module.UserInfo: obj1, # obj1 = AryaConfig(models.UserInfo,site),
module.UserType: obj2, # obj2 = AryaConfig(models.UserType,site),
}
:param class_name: models類
:param config_class: 對應(yīng)的View類(AryaConfig)
:return:
"""
self._registry[class_name] = config_class(class_name, self)
@property
def urls(self):
"""
處理子路由
:return:
"""
partterns = [
url(r'^login/$', self.login),
url(r'^logout/$', self.logout),
]
# 循環(huán)self._registry屬性里面的每一個元素檐嚣,key為models類助泽,value為URLS對應(yīng)處理的類obj對象
for model_class, arya_config_obj in self._registry.items():
# 分別為app名稱和models的類名稱
print("*" * 50)
print(model_class._meta.app_label, model_class._meta.model_name)
app_model_name_urls = r'^{0}/{1}/'.format(model_class._meta.app_label, model_class._meta.model_name)
# arya_config_obj.urls self._registry字典中存放的values對象obj下面的urls方法
pt = url(app_model_name_urls, (arya_config_obj.urls, None, None))
partterns.append(pt)
# 3元組
return partterns, None, None
def login(self):
"""
登陸
:return:
"""
return redirect('login')
def logout(self):
"""
退出
:return:
"""
return redirect('login')
# 實例化啰扛,利用單例模式
site = AryaSite()
</br>
引入arya組件并使用
- 創(chuàng)建app,引入arya組件
創(chuàng)建多個app嗡贺,并在每個app下面創(chuàng)建arya.py文件隐解,用于實現(xiàn)CURD操作
django startapp app01
...
- 在app01下面創(chuàng)建models模型
# cat app01/models.py
from django.db import models
class UserType(models.Model):
"""
用戶類型表
"""
title = models.CharField(max_length=32, verbose_name="用戶類型")
class Meta:
verbose_name_plural = "用戶類型表"
def __str__(self):
return self.title
class Role(models.Model):
"""
角色表
"""
caption = models.CharField(max_length=32, verbose_name="角色名")
class Meta:
verbose_name_plural = "角色表"
def __str__(self):
return self.caption
class UserInfo(models.Model):
"""
用戶表
"""
username = models.CharField(max_length=32, verbose_name="用戶名")
password = models.CharField(max_length=64, verbose_name="密碼")
email = models.CharField(max_length=32, verbose_name="郵箱")
ut = models.ForeignKey(to="UserType", blank=True, verbose_name="用戶類型")
roles = models.ManyToManyField(to="Role", blank=True, verbose_name="所屬角色")
class Meta:
verbose_name_plural = "用戶表"
def __str__(self):
return self.username
生成表結(jié)構(gòu)并制作部分展示數(shù)據(jù),可以直接在表中添加诫睬,也可以通過admin后臺進(jìn)行添加
在app01中的arya.py文件中注冊models類并自定義實現(xiàn)展示UI
# cat app01/arya.py
from arya.service import v1
from . import models
# 自定義屬性控制UI展示
class UserInfoConfig(v1.AryaConfig):
"""
自定義用戶信息UI
"""
list_display = ['username', 'ut', 'roles', 'email']
class UserTypeConfig(v1.AryaConfig):
"""
自定義用戶類型UI
"""
list_display = ['title']
class RoleConfig(v1.AryaConfig):
"""
自定義角色UI
"""
list_display = ['caption']
# 注冊models
v1.site.register(models.UserInfo, UserInfoConfig)
v1.site.register(models.UserType, UserTypeConfig)
v1.site.register(models.Role, RoleConfig)
- 在項目中應(yīng)用arya組件煞茫,使URL生效
#cat project_name/urls.py
from django.contrib import admin
from django.conf.urls import url
from arya.service import v1
from . import views
# url的第二個參數(shù)返回類型為([],None,None)的元組,源碼見include方法
# 此處的login和logut也可以使用arya/service/v1.py文件中定義的路由,示例為自己實現(xiàn)
urlpatterns = [
url(r'^admin/', admin.site.urls),
# 此處會生成對應(yīng)的多個URL子路由
url(r'^arya/', v1.site.urls),
url(r'^index/$', views.index, name="index"),
url(r'^login/$', views.login, name="login"),
url(r'^logout/$', views.logout, name="logout"),
]
- 路由試圖處理
# cat project_name/views.py
from django.shortcuts import render, redirect
from app01 import models
def login(request):
"""
登陸
:param request:
:return:
"""
if request.method == "GET":
return render(request, 'login.html')
else:
username = request.POST.get('username')
password = request.POST.get('password')
obj = models.UserInfo.objects.filter(username=username, password=password).first()
if obj:
request.session['userinfo'] = {'username': obj.username, 'is_login': True}
return redirect('index')
return render(request, 'login.html', {'msg': '用戶名或密碼錯誤'})
def logout(request):
"""
退出
:param request:
:return:
"""
if request.method == "GET":
return redirect('login')
def index(request):
"""
首頁
:param request:
:return:
"""
if request.method == "GET":
return render(request, 'index.html')
- 項目URL
此時在項目的路由中已經(jīng)存在對應(yīng)增刪改查的4個URL摄凡,如下所示:
# app_nmae 應(yīng)用名
# models_name models類名小寫
arya/app_name/models_name/
arya/app_name/models_name/add/
arya/app_name/models_name/(\d+)/change/
arya/app_name/models_name/(\d+)/delete/
# 在該示例中為:
http://127.0.0.1:8000/arya/app01/userinfo/
http://127.0.0.1:8000/arya/app01/userinfo/add/
http://127.0.0.1:8000/arya/app01/userinfo/()
....
- 擴(kuò)展
在每個app下面的arya.py文件中繼承arya組件中的service.v1.AryaConfig類续徽,自己內(nèi)部實現(xiàn)處理URL的view以及定制化操作
</br>
總結(jié)
至此,自定義實現(xiàn)的類似Django admin組件基本開發(fā)完成亲澡,能夠滿足models模型數(shù)據(jù)的CURD操作钦扭。在Django中作為app引入CustAdmin組件,然后在settings文件中注冊后就
可以生效使用了,engoy it!