Admin注册和路由分发详解

1.启动

#autodiscover_modules('admin', register_to=site)

2.注册

1.单例对象
admin.site = AdminSite(): 单例对象
AdminSite 源码:
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)}

ModelAdmin部分源码:
class ModelAdmin(BaseModelAdmin):
list_display = ('__str__',)
list_display_links = ()
list_filter = ()
search_fields = ()
actions = []
def __init__(self, model, admin_site):
self.model = model
self.opts = model._meta
self.admin_site = admin_site
super(ModelAdmin, self).__init__()
def __str__(self):
return "%s.%s" % (self.model._meta.app_label, self.__class__.__name__)
BaseModelAdmin部分源码:
def __init__(self):
overrides = copy.deepcopy(FORMFIELD_FOR_DBFIELD_DEFAULTS)
for k, v in self.formfield_overrides.items():
overrides.setdefault(k, {}).update(v)
self.formfield_overrides = overrides

2.在admin中注册模型对象

from django.contrib import admin
1.admin.site.register(Book) # admin.site._registry={Book:ModelAdmin(Book)}
1.admin.site是AdminSite()实例化出的对象,并且是单例对象,程序中的admin.site都是同一对象,指向同一内存地址
2.admin.site.register(Book)执行类AdminSite中的register方法,参数model为注册的模型对象BOOK
3.如果只传Book,则admin_class为Django自定义类ModelAdmin
4.self._registry[model] = admin_class(model, self) 为self._registry[Book] = admin_class(Book, self)
即self._registry = {Book:ModelAdmin(Book)} Book是一个对象
5.ModelAdmin实例化出book这个表
2.admin.site.register(Publish) 
继续注册另一模型对象时,仍走上述步骤,但此时 self._registry 不再为{},而是{Book:ModelAdmin(Book)},注册完Publisher后
admin.site._registry={Book:ModelAdmin(Book),Publish:ModelAdmin(Publish)}
3.自定义admin_class,自定的类必须继承admin。ModelAdmin
class Authoconfig(admin.ModelAdmin):pass
admin.site.register(Author, Authoconfig) admin_class=Authoconfig {Author:Authoconfig(Author)}
此时:admin.site._registry={Book:ModelAdmin(Book),Publish:ModelAdmin(Publish),Author:Authoconfig(Author)}
4.启动Django后,会自定义group和user两张表,此时打开admin页面会有五张表
5.在Django中新建app02,在admin中注册新的模型对象
 在settings中:
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'app01.apps.App01Config',
'app02.apps.App02Config',
]
启动Django后,先加载admin,然后执行app01下的apps文件,自动扫描自身和其他app的admin文件,生成admin.site对象。并将app01中模型对象注册到registry中,再执行app02,加载app02
中的admin,将模型对象注册到registry中,此时registry中不为空,存放着app01注册的对象
例:在app01的admin中注册,打印查看
from django.contrib import admin
# Register your models here.
from app01 import models
admin.site.register(models.Book)
print("1====>",admin.site._registry) #此时三张表 user group book
admin.site.register(models.Publish)
admin.site.register(models.Author)
admin.site.register(models.AuthorDetail)
print("2====>",admin.site._registry) ##此时六张表 user group book Publish Author AuthorDetail
====> {<class 'django.contrib.auth.models.Group'>: <django.contrib.auth.admin.GroupAdmin object at 0x0000018D386F2E80>, <class 'django.contrib.auth.models.User'>: <django.contrib.auth.admin.UserAdmin object at 0x0000018D38721908>, <class 'app01.models.Book'>: <django.contrib.admin.options.ModelAdmin object at 0x0000018D38739518>}
====> {<class 'django.contrib.auth.models.Group'>: <django.contrib.auth.admin.GroupAdmin object at 0x0000018D386F2E80>, <class 'django.contrib.auth.models.User'>: <django.contrib.auth.admin.UserAdmin object at 0x0000018D38721908>, <class 'app01.models.Book'>: <django.contrib.admin.options.ModelAdmin object at 0x0000018D38739518>, <class 'app01.models.Publish'>: <django.contrib.admin.options.ModelAdmin object at 0x0000018D38739400>, <class 'app01.models.Author'>: <django.contrib.admin.options.ModelAdmin object at 0x0000018D38739588>, <class 'app01.models.AuthorDetail'>: <django.contrib.admin.options.ModelAdmin object at 0x0000018D387395C0>}
在app02中注册order表
from app02 import models
admin.site.register(models.Order)
print("3====>",admin.site._registry)
##此时七张表 user group book Publish Author AuthorDetail order
#进入admin后,能看到app01里面的表ye能看到app02的表
====> {<class 'django.contrib.auth.models.Group'>: <django.contrib.auth.admin.GroupAdmin object at 0x0000018D386F2E80>, <class 'django.contrib.auth.models.User'>: <django.contrib.auth.admin.UserAdmin object at 0x0000018D38721908>, <class 'app01.models.Book'>: <django.contrib.admin.options.ModelAdmin object at 0x0000018D38739518>}
====> {<class 'django.contrib.auth.models.Group'>: <django.contrib.auth.admin.GroupAdmin object at 0x0000018D386F2E80>, <class 'django.contrib.auth.models.User'>: <django.contrib.auth.admin.UserAdmin object at 0x0000018D38721908>, <class 'app01.models.Book'>: <django.contrib.admin.options.ModelAdmin object at 0x0000018D38739518>, <class 'app01.models.Publish'>: <django.contrib.admin.options.ModelAdmin object at 0x0000018D38739400>, <class 'app01.models.Author'>: <django.contrib.admin.options.ModelAdmin object at 0x0000018D38739588>, <class 'app01.models.AuthorDetail'>: <django.contrib.admin.options.ModelAdmin object at 0x0000018D387395C0>}
====> {<class 'django.contrib.auth.models.Group'>: <django.contrib.auth.admin.GroupAdmin object at 0x0000018D386F2E80>, <class 'django.contrib.auth.models.User'>: <django.contrib.auth.admin.UserAdmin object at 0x0000018D38721908>, <class 'app01.models.Book'>: <django.contrib.admin.options.ModelAdmin object at 0x0000018D38739518>, <class 'app01.models.Publish'>: <django.contrib.admin.options.ModelAdmin object at 0x0000018D38739400>, <class 'app01.models.Author'>: <django.contrib.admin.options.ModelAdmin object at 0x0000018D38739588>, <class 'app01.models.AuthorDetail'>: <django.contrib.admin.options.ModelAdmin object at 0x0000018D387395C0>, <class 'app02.models.Order'>: <django.contrib.admin.options.ModelAdmin object at 0x0000018D387395F8>}
'''

3.路由设计

1.路由的写法:
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^zhao/', zhao),
]

2.路由分发:
拼接路由 url(r"^jerd/",([],None,None)) 后面的是元祖,在[]中写url(r'^zhao/', zhao)形式
一级路由分发 url(r"^jerd/",([],None,None))
url(r"^jerd/",([
url(r'^test1/',test1), 在网页上输入时jerd后面必须添加拼接的路径,不然显示不出来
url(r'^test2/', test2),
url(r'^test3/', test3),
],None,None)),
二级路由分发 url(r"^jerd/"([url(r'^test1/',([],None,None)), ],None,None))
 url(r"^jerd/", ([
url(r'^test1/', ([
url(r"^test5/", test5),
url(r"^test6/", test6),
], None, None)), url(r'^test2/', test2),
url(r'^test3/', test3),
], None, None)),
3.设计执行函数:
def zhao(request):
return HttpResponse("这是zhaogaungfei的网页")
def test1(request):
return HttpResponse("这是test1的网页")
def test2(request):
return HttpResponse("这是test2的网页")
def test3(request):
return HttpResponse("这是test3的网页")
def test5(request):
return HttpResponse("这是test5的网页")
def test6(request):
return HttpResponse("这是test6的网页")
4.封装路由:
在admin中一共有7张表,每张都能进行增,删,改,查四种操作,设置相关路由操作,
#单个写的话需要28个路由。封装这些路由
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^Xadmin/', (get_urls(),None,None)),
]
封装路由
 
#二级路由:
def get_url_2():
temp=[]
temp.append(url(r"^$",list_view))
temp.append(url(r"^add/$", add_view))
temp.append(url(r"^(\d+)/change/$", change_view))
temp.append(url(r"^(\d+)/del/$", del_view))
return temp
#一级路由:
def get_urls():
temp=[]
# 能查看在admin中刚注册的表 {Book:ModelAdmin(Book)} 字典中的Book是对象,而在路由上输入的是字符串,需要转换
print(admin.site._registry)
for model,admin_class in admin.site._registry.items():
app_name=model._meta.app_label #拿到app的名字
model_name=model._meta.model_name #拿到字符串类型的表名
temp.append(url(r"^{}/{}/".format(app_name,model_name),(get_url_2(),None,None)),)
return temp
def list_view(request):
return HttpResponse("这是查看的网页")
def add_view(request):
return HttpResponse("这是添加的网页")
def change_view(request,id):
return HttpResponse("这是编辑的网页")
def del_view(request,id):
return HttpResponse("这是删除的网页")
 

Admin注册和路由分发详解的更多相关文章

  1. C#Winform 注册使用全局快捷键详解

    C#.NET Winform 注册使用全局快捷键详解 借助于全局快捷键,用户可以在任何地方操控程序,触发对应的功能.但 WinForms 框架并没有提供全局快捷键的功能.想要实现全局快捷键需要跟 Wi ...

  2. django中的路由控制详解

    一 Django中路由的作用 二 简单的路由配置 三 有名分组 四 路由分发 五 反向解析 六 名称空间 七 django2.0版的path 一 Django中路由的作用 URL配置(URLconf) ...

  3. ThinkPHP5——route(路由)的详解

    路由在框架中的作用打个比方的话,路由好比是WEB应用的总调度室,对于访问的URL地址,路由可以拒绝或者接受某个URL请求,并进行分发调度,而且还有一个副作用是因为路由规则可以随意定义,因此可以让你的U ...

  4. ASP.NET MVC5 新特性:Attribute路由使用详解 (转载)

    1.什么是Attribute路由?怎么样启用Attribute路由? 微软在 ASP.NET MVC5 中引入了一种新型路由:Attribute路由,顾名思义,Attribute路由是通过Attrib ...

  5. ASP.NET MVC5 新特性:Attribute路由使用详解

    1.什么是Attribute路由?怎么样启用Attribute路由? 微软在 ASP.NET MVC5 中引入了一种新型路由:Attribute路由,顾名思义,Attribute路由是通过Attrib ...

  6. SPA路由机制详解(看不懂不要钱~~)

    前言 总所周知,随着前端应用的业务功能起来越复杂,用户对于使用体验的要求越来越高,单面(SPA)成为前端应用的主流形式.而大型单页应用最显著特点之一就是采用的前端路由跳转子页面系统,通过改变页面的UR ...

  7. ASP.NET MVC5 :Attribute路由使用详解

    1.什么是Attribute路由?怎么样启用Attribute路由? 微软在 ASP.NET MVC5 中引入了一种新型路由:Attribute路由,顾名思义,Attribute路由是通过Attrib ...

  8. Android系统输入事件分发详解

    什么是输入事件? 我们知道,运行android系统的设备本质上是一台计算机,使用者在和计算机进行交互的时候可以抽象成简单的对计算机的输入和输出(IO).那么对于运行在计算机上的操作系统来说,操作系统在 ...

  9. typecho路由机制详解

    本文介绍的是typecho的路由机制,引自 不烦恼路由机制是typecho的核心,有很多功能都是基于路由功能设计的,理解并熟悉TE的路由机制将非常有助于插件的开发. 完整的路由表如下: array ( ...

随机推荐

  1. System.Object

    Object():System.Object类型的构造函数,自动调用. ~Object()/Finalize():System.Object类型的祈构函数,自动调用且不能够手动. Equals(obj ...

  2. SQL 查询当天,本月,本周的记录

    SELECT * FROM 表 WHERE CONVERT(Nvarchar, dateandtime, 111) = CONVERT(Nvarchar, GETDATE(), 111)   ORDE ...

  3. 如何在myeclipse中安装spket插件

    在web开发中,经常会遇到自动提示,比如jquery.extjs等,在myeclipse写这些代码时需要自动提示,就需要安装spket插件,具体方法见下面 工具/原料   myeclipse spke ...

  4. eclipse开启时报错问题

    eclipse启动时报如下错误: Unable to read workbench state.Workbench UI layout will be reset 不能找到正式的工作台,工作台UI的布 ...

  5. Padavan老毛子固件:17CE插件集成

    Padavan老毛子固件:17CE插件集成 1.老毛子路由设置:系统管理-服务-启动SSH服务器     以下链接下载 "winscp" http://down.orsoon.co ...

  6. ubuntu16.04 安装最新版nodejs

    ubuntu软件仓库中自带的nodejs版本过低 $ apt-cache policy nodejs nodejs: Installed: (none) Candidate: 4.2.6~dfsg-1 ...

  7. Django中media的配置

    Django中media的配置 Django中media文件夹是我们文件(比如头像.文件.视频等)数据十分重要的存放处,这里以用户头像的上传以及media文件的访问为例为大家详细讲解下media的相关 ...

  8. AI与RPA

    RPA(机器人流程自动化)是一类自动化软件工具,它可以通过用户界面使用和理解企业已有的应用,将基于规则的常规操作自动化,例如读取邮件和系统,计算,生成文件和报告,检查文件等.因此,RPA的应用范围非常 ...

  9. java中如何给控件设置颜色

     1. tv.setTextColor(Color.parseColor("#000000"));2. tv.setTextColor(getResources().getCo ...

  10. PHP常用的转义函数

    1. addslashes addslashes对SQL语句中的特殊字符进行转义操作,包括(‘), (“), (), (NUL)四个字符,此函数在DBMS没有自己的转义函数时候使用,但是如果DBMS有 ...