Django之admin
一、admin简介
admin为Django提供的后台管理工具,可以通过“http://127.0.0.1:8000/admin/”进行访问,访问是需要用户名和密码(可以在创建的Django项目命令行下创建 “python manage.py createsuperuser” )
如果想在后台看到admin管理的对象(数据对象),首先要在Django所创建的app中的admin.py注册数据对象,代码如下:
class BookConfig(admin.ModelAdmin): def deletes(self): return mark_safe("<a href=''>删除</a>") list_display = ["title","publish","publishDate","price",deletes] #list_display_links = ["title","publish","publishDate","price",] list_display_links = ["publish", "publishDate", "price", ] list_filter = ["price","authors","publish",] list_editable = ["title",] search_fields = ["title", "price"] def patch_init(self,request,queryset): queryset.update(price=100) patch_init.short_description = "批量初始化" actions = [patch_init,] #change_list_template = "list.html" fields = ("title",) admin.site.register(models.Book,BookConfig) admin.site.register(models.AuthorDetail) admin.site.register(models.Author)
红色部分为正常注册,如果需要向admin界面中添加更多功能(样式),则需要在配置是加入第二个参数:配置类(代码蓝色--样式类),配置类需要继承admin.ModelAdmin类,具体参数配置可以查看admin.ModelAdmin源码
二、Admin的实现流程:
1、启动;
当Django启动时,程序扫描setting.py,加载INSTALLED_APPS下的每个app,加载django.contrib.admin时,django.contrib.admin下的autodiscover方法自动扫描加载每个app下的admin.py文件
def autodiscover(): autodiscover_modules('admin', register_to=site)
2、注册;
admin.site(单例对象)
admin.site.register(模型对象)
#源代码解析
class AdminSite(object): ...... def __init__(self, name='admin'): self._registry = {} ...... def register(self, model, admin_class=None, **options): if not admin_class: admin_class = ModelAdmin ...... self._registry[model] = admin_class(model, self) # {Book:ModelAdmin(Book)} #admin.site.register(Book) #admin.site._registry={Book:ModelAdmin(Book)} #admin.site.register(Publish) #admin.site._registry={Book:ModelAdmin(Book),Publish:ModelAdmin(Publish)} #class Authoconfig(admin.ModelAdmin): pass admin.site.register(Author,Authoconfig) # admin.site._registry={Book:ModelAdmin(Book),Publish:ModelAdmin(Publish),Author:Authoconfig(Author)}
3、设计URL
在此以模型类Book为例,每一个app下的模型类,后台管理提供增删改查四个url:
127.0.0.1:8000/admin/app01/book/
127.0.0.1:8000/admin/app01/book/add/
127.0.0.1:8000/admin/app01/book/1/change/
127.0.0.1:8000/admin/app01/book/1/delete/
Django内部实现:
path('admin/', admin.site.urls)#实现所有模型类的增删改查url的分发
下面为自定义URL分发(当然,你也可以自己尝试重构admin的url分发,原理是一样的)
from django.contrib import admin from django.urls import path from django.conf.urls import url from app01 import views from django.shortcuts import HttpResponse def get_urls2(): temp=[]
temp.append(url(r"^$",views.list_view)) temp.append(url(r"^add/$", views.add_view)) temp.append(url(r"^(\d+)/change/$", views.change_view)) temp.append(url(r"^(\d+)/delete/$", views.delete_view)) return temp def get_urls(): #print(admin.site._registry) temp=[] for model,admin_class_obj in admin.site._registry.items():#admin.site._registry.items(所有注册过的模型类)
#model对应模型类,admin_class_obj 对应自定义样式类
app_name=model._meta.app_label
model_name=model._meta.model_name
print(app_name,model_name)
temp.append(url(r'^{0}/{1}/'.format(app_name,model_name),(get_urls2(),None,None)),)
return temp
urlpatterns = [
path('admin/', admin.site.urls),
url(r'^Xadmin/',(get_urls(),None,None)),
]
4、Xadmin注册
下面是关于Xadmin,Xadmin其实是自定义的admin,通过以上对admin源码的分析,我们可以自己构造出admin——Xadmin。
Xadmin注册流程:
1)新建Django项目,创建名为Xadmin的app;
2)在Xadmin中创建Xadmin,代码如下:
from django.conf.urls import url
from django.shortcuts import HttpResponse,render
class ModelXadmin(object):
def __init__(self,model,site):
self.model=model
self.site=site
def list_view(self, request):
print(self.model)
data_list=self.model.objects.all()
return render(request, "list_view.html",{"data_list":data_list})
def add_view(self, request):
return render(request, "add_view.html")
def change_view(self, request, id):
return render(request, "change_view.html")
def delete_view(self, request, id):
return render(request, "delete_view.html")
def get_urls2(self):
temp = []
temp.append(url(r"^$", self.list_view))
temp.append(url(r"^add/$", self.add_view))
temp.append(url(r"^(\d+)/change/$", self.change_view))
temp.append(url(r"^(\d+)/delete/$", self.delete_view))
return temp
@property
def urls2(self):
return self.get_urls2(), None, None
class XadminSite(object):
def __init__(self,name="admin"):
self._registry={}
def get_urls(self):
temp = []
for model, admin_class_obj in self._registry.items():
app_name = model._meta.app_label
model_name = model._meta.model_name
temp.append(url(r'^{0}/{1}/'.format(app_name, model_name), admin_class_obj.urls2), )
return temp
@property
def urls(self):
return self.get_urls(), None, None
def register(self,model,admin_class=None,**options):
if not admin_class:
admin_class=ModelXadmin
self._registry[model]=admin_class(model,self)
site=XadminSite()#基于模块的单例对象
首先,仿照admin源码实现__init__和register方法;其次,实现url分发;最后,实例化一个单例对象。
使用,新建一个app,并新建一个Xadmin.py,将app的模型类在此Xadmin中注册,代码如下:
print("app01_Xadmin") from app01.models import * #自定义注册 site.register(Book) site.register(Publish) site.register(Author) site.register(AuthorDetail) #原始注册 #admin.site.register()