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
1====> {<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>}
2====> {<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的表
1====> {<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>}
2====> {<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>}
3====> {<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>}
'''
View Code

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("这是删除的网页")
View Code
 
 
 


 
 
 
 
 
原文地址:https://www.cnblogs.com/zgf-666/p/9129683.html