1、admin的源碼流程django
首先能夠肯定的是:路由關係必定對應一個視圖函數app
a、當點擊運行的時候,會先找到每個app中的admin.py文件,並執行函數
b、執行urls.py post
admin.site是什麼?url
admin.site,urls 返回的是一個元組,裏面的第一個元素是一個列表spa
django-admin的源碼流程 咱們本身生成的動態的訪問url ====================================初級版========================= from django.shortcuts import HttpResponse from django.conf.urls import url from django.contrib import admin from app01 import views def login(request): return HttpResponse("ok") url_list = [] for model_class,v in admin.site._registry.items(): print(model_class) #打印的是每個類<class 'app01.models.UserInfo'> cls_name = model_class._meta.model_name #當前類名稱的小寫 app_name = model_class._meta.app_label #當前app的名稱 val = url(r'^{0}/{1}/$'.format(app_name,cls_name), login, name="login") url_list.append(val) urlpatterns = [ url(r'^admin/', admin.site.urls), # admin.site這個對象裏面有一個屬性_registry = {} #點擊urls查看源碼返回的是一個元組,元組的第一個元素是一個列表 url(r'^index/', ([ url(r'^app01/userinfo/$', login,name="login"), url(r'^app01/roles/$', login,name="login"), ],None,None)), url(r'^index2/', (url_list,None,None,)), #吧上面定義的列表拿下來,這是後就動態生成了 ]
================================升級============================ 路徑http://127.0.0.1:8001/index/app01/roles/後面還有增刪改查的路徑 http://127.0.0.1:8001/index/app01/roles/add/ http://127.0.0.1:8001/index/app01/roles/1/change/ http://127.0.0.1:8001/index/app01/roles/1/del/ 實現流程 from django.shortcuts import HttpResponse from django.conf.urls import url from django.contrib import admin from app01 import views def login(request): return HttpResponse("ok") def change_list(request): return HttpResponse("列表頁面") def add_view(request): return HttpResponse("添加頁面") def change_view(request,nid): return HttpResponse("修改頁面") def delete_view(request,nid): return HttpResponse("刪除頁面") url_list = [] for model_class,v in admin.site._registry.items(): print(model_class) #打印的是每個類<class 'app01.models.UserInfo'> cls_name = model_class._meta.model_name #當前類名稱的小寫 app_name = model_class._meta.app_label #當前app的名稱 urls_list = url(r'^{0}/{1}/$'.format(app_name,cls_name), change_list, name="login") url_list.append(urls_list) add_url = url(r'^{0}/{1}/add/$'.format(app_name, cls_name), add_view, name="login") url_list.append(add_url) change_url = url(r'^{0}/{1}/(\d+)/change/$'.format(app_name, cls_name), change_view, name="login") url_list.append(change_url) del_url = url(r'^{0}/{1}/(\d+)/del/$'.format(app_name, cls_name), delete_view, name="login") url_list.append(del_url) urlpatterns = [ url(r'^admin/', admin.site.urls), # admin.site這個對象裏面有一個屬性_registry = {} #點擊urls查看源碼返回的是一個元組,元組的第一個元素是一個列表 url(r'^index/', ( [ url(r'^app01/userinfo/$', login,name="login"), url(r'^app01/roles/$', login,name="login"), ],None,None)), url(r'^index2/', (url_list,None,None,)), #吧上面定義的列表拿下來,這是後就動態生成了 ] 說明了: url的本質:它讀取_registry全部字典裏面的數據,爲字典裏面的每個類生成了4個url
==================================修改上面的版本============================= 定義了一個 def get_urls(): temp = [ url(r'^$'.format(app_name, cls_name), change_list), url(r'^add/$'.format(app_name, cls_name), add_view), url(r'^del/$'.format(app_name, cls_name), delete_view), url(r'^change/$'.format(app_name, cls_name), change_view) ] return temp url_list = [] for model_class,v in admin.site._registry.items(): print('-------',model_class) #打印的是每個類<class 'app01.models.UserInfo'> cls_name = model_class._meta.model_name #當前類名稱的小寫 app_name = model_class._meta.app_label #當前app的名稱 方式一: # all_urls = url(r'^{0}/{1}/'.format(app_name,cls_name), (get_urls(),None,None,)) 方式二: all_urls = url(r'^{0}/{1}/'.format(app_name,cls_name), include(get_urls()) ) url_list.append(all_urls) urlpatterns = [ url(r'^admin/', admin.site.urls), # admin.site這個對象裏面有一個屬性_registry = {} #點擊urls查看源碼返回的是一個元組,元組的第一個元素是一個列表 url(r'^index/', ( [ url(r'^app01/userinfo/', ([ url(r'^$', change_list, name="login"), url(r'^add/$', add_view, name="login"), url(r'^(\d+)/del/$', delete_view, name="login"), url(r'^(\d+)/change/$', change_view, name="login"), ],None,None),name="login"), url(r'^app01/usertype/', ([ url(r'^$', change_list, name="login"), url(r'^add/$', add_view, name="login"), url(r'^(\d+)/del/$', delete_view, name="login"), url(r'^(\d+)/change/$', change_view, name="login"), ], None, None), name="login"),],None,None)), url(r'^app02/article/', ([ url(r'^$', change_list, name="login"), url(r'^add/$', add_view, name="login"), url(r'^(\d+)/del/$', delete_view, name="login"), url(r'^(\d+)/change/$', change_view, name="login"), ],None,None),name="login"), # index和index2的兩個是同樣的,咱們能夠用index2的方式替代index url(r'^index2/', (url_list,None,None,)), #吧上面定義的列表拿下來,這是後就動態生成了 ] include的本質就是:返回了一個元組,元組的第一個是這個模塊 include裏面 既能夠寫一個列表include([]),利用include作分發 也能夠返回一個字符串:幫咱們去找到這個模塊,找到全部的映射關係 include(model_admin.urls) model_admin是什麼?ModelAdmin對象的urls
總結code
- admin源碼流程 a. 運行程序,找到每個app中的 admin.py 文件,並加載 - app01.admin.py - 建立admin.site中的對象 - 執行對象的 register方法,目的:將註冊類添加到 _registry中 _registry = { key是傳進來的model value:是ModelAdmin的對象,傳了兩個參數 models.Role: ModelAdmin(models.Role,admin.site), models.UserInfo: ModelAdmin(models.UserInfo,admin.site) models.UserType: ModelAdmin(models.UserType,admin.site) } - app02.admin.py - 用app01.admin中建立那個admin.site對象 - 執行對象的 register方法,目的:講註冊類添加到 _registry中 _registry = { models.Role: ModelAdmin(models.Role,admin.site), models.UserInfo: ModelAdmin(models.UserInfo,admin.site) models.UserType: ModelAdmin(models.UserType,admin.site) models.Article: ModelAdmin(models.Article,admin.site) } admin.site是一個對象(單例模式建立),其中封裝了: _registry = { models.Role: ModelAdmin(models.Role,admin.site), models.UserInfo: ModelAdmin(models.UserInfo,admin.site) models.UserType: ModelAdmin(models.UserType,admin.site) models.Article: ModelAdmin(models.Article,admin.site) } b. urls.py 再次調用 admin.site 對象的 urls屬性: urlpatterns = [ url(r'^admin/', admin.site.urls), ] class ModelAdmin(object): def __init__(self,model_class,site): self.model_class = model_class self.site = site def changelist_view(self,request): data_list = self.model_class.objects.all() #是動態的 return HttpResponse('列表頁面') def add_view(self,request): return HttpResponse('添加頁面') def delete_view(self,request,nid): return HttpResponse('刪除頁面') def change_view(self,request,nid): return HttpResponse('修改頁面') def get_urls(self): urlpatterns = [ url(r'^$', self.changelist_view), url(r'^add/$', self.add_view), url(r'^(.+)/delete/$', self.delete_view), url(r'^(.+)/change/$', self.change_view), ] return urlpatterns @property def urls(self): return self.get_urls() class AdminSite(object): def __init__(self): self._registry = {} def register(self,model_class,model_admin): self._registry[model_class] = model_admin(model_class,self) def get_urls(self): """ models.Role: ModelAdmin(models.Role,admin.site), models.UserInfo: ModelAdmin(models.UserInfo,admin.site) models.UserType: ModelAdmin(models.UserType,admin.site) models.Article: ModelAdmin(models.Article,admin.site) """ url_list = [] for model_class,model_admin in self._registry.items(): model_class是一個類 app_name = model_class._meta.app_label model_name = model_class._meta.model_name url_list += [ url('%s/%s' %(app_name,model_name,), include(model_admin.urls)) ] return url_list @property def urls(self): return (self.get_urls(), None,None )