Django 自帶的用戶後臺組件javascript
用於用戶便攜的操做html
每一個app 經過 apps.py 掃描 admin.py 文件 並執行java
""" setting.py setting.py 中會對註冊的 app 自動加載各自裏面的 AppxxConfig 模塊 """ INSTALLED_APPS = [ ... 'app01.apps.App01Config', 'app02.apps.App02Config', ]
""" apps.py app下的裏面的 adminConfig 在自動執行的時候能夠進行啓動操做 """ from django.apps import AppConfig class App01Config(AppConfig): name = 'app01'
""" admin 源碼 調用每一個app 下的admin.py 文件進行執行 """ import admin # 執行每個app下的admin.py文件 autodiscover_modules('admin', register_to=site)
""" admin.py 被執行的 admin.py 文件 """ from django.contrib import admin from rbac.models import * # Register your models here.
在admin.py 文件中對錶進行註冊django
註冊後的表要判斷是否有自定義的配置文件app
若沒有則使用默認的 Modeladmin函數
""" admin 註冊流程核心源碼 """ 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),Publi sh:ModelAdmin(Publish)} # 進行實例化實現單例模式 # 其餘全部的程序中的 admin 經過引入,用的都是這個對象 site=AdminSite()
""" admin.py 中對錶進行註冊操做 """ from django.contrib import admin from rbac.models import * # Register your models here. # 基於模塊的單例模式從而實現全部的註冊表都使用的同一個 admin.site 對象 admin.site.register(User) admin.site.register(Role) admin.site.register(Permission)
調用 urls() 方法url
而後繼續調用 get_urls() 方法spa
遍歷全部註冊表,進行URL 的拼接合成最後生成一個列表返回給 urls.py設計
最終在urls.py 進行調用code
""" urls.py urls.py 中所有寫成了一條 全部的結果都在調用 urls方法後拿到 """ urlpatterns = [ url(r'^admin/', admin.site.urls), ]
""" admin 設計url 核心 """ class AdminSite(object): def get_urls(self): urlpatterns = [ url(r'^$', wrap(self.index), name='index'), url(r'^login/$', self.login, name='login'), url(r'^logout/$', wrap(self.logout), name='logout'), url(r'^password_change/$', wrap(self.password_change, cacheable=True), name='password_change'), url(r'^password_change/done/$', wrap(self.password_change_done, cacheable=True), name='password_change_done'), url(r'^jsi18n/$', wrap(self.i18n_javascript, cacheable=True), name='jsi18n'), url(r'^r/(?P<content_type_id>\d+)/(?P<object_id>.+)/$', wrap(contenttype_views.shortcut), name='view_on_site'), ] valid_app_labels = [] # 遍歷註冊過的表,對每一個表生成 相應的 url 進行連接起來 for model, model_admin in self._registry.items(): urlpatterns += [ url(r'^%s/%s/' % (model._meta.app_label, model._meta.model_name), include(model_admin.urls)), ] if model._meta.app_label not in valid_app_labels: valid_app_labels.append(model._meta.app_label) if valid_app_labels: regex = r'^(?P<app_label>' + '|'.join(valid_app_labels) + ')/$' urlpatterns += [ url(regex, wrap(self.app_index), name='app_list'), ] # 返回給urls 得出的 urls列表 # 全部的urls 保存在 urlpatterns列表裏面 return urlpatterns # 調用 get_urls 得到所有的結果 def urls(self): # 給urls.py 返回回去 return self.get_urls(), 'admin', self.name
ps:
url 的設計和分發合成是何時完成?
答案:
在項目啓動的時候就完成
在表進行註冊後,就已經生成了,而不是url來了再生成
本質上 django 啓動就已是啓動了文件,否則你的admin 單例從何而來
""" 本身實現一個 Xadmin 模塊來替換掉 admin 和 admin 同樣須要 啓動 註冊 url 分發 """ """ 啓動 """ # setting.py INSTALLED_APPS = [ ... 'Xadmin.apps.XadminConfig', 'app01.apps.App01Config', 'app02.apps.App02Config', ] # apps.py from django.apps import AppConfig from django.utils.module_loading import autodiscover_modules # Xadmin.py class XadminConfig(AppConfig): name = 'Xadmin' """ 啓動 """ def ready(self): autodiscover_modules('Xadmin') class ModelXadmin(object): def __init__(self,model,site): self.model=model self.site=site """ url 分發 二級分發和視圖函數放在 配置類裏面 不放在 註冊類裏面的緣由: 由於註冊類 單例生成 致使全部的註冊表的self裏面沒法區分出來彼此的 配置類 若是放在 配置類中 self 就是註冊表本身對應的 配置類 根本拿不到想要的數據(好比 表 自己) 好比 在 配置類 中 self.model 就是那個表,(在init 中註冊的均可以隨便拿來用了) """ def list_view(self, request): print("self.model",self.model) data_list=self.model.objects.all() print("data_list",data_list) 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 register(self, model, admin_class=None, **options): if not admin_class: admin_class = Modeladmin self._registry[model] = admin_class(model, self) """ url 分發 """ 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 site=XadminSite()
# url.py from Xadmin.service.Xadmin import site urlpatterns = [ url(r'^admin/', admin.site.urls), url(r'^Xadmin/', site.urls), ] """ 其餘的程序使用方式
和以往admin的方式基本一致 """ """ 啓動 """ # setting.py INSTALLED_APPS = [ ... 'app01.apps.App01Config', "app02.apps.App02Config" ] # apps.py from django.apps import AppConfig class App01Config(AppConfig): name = 'app01' # Xadmin.py from Xadmin.service.Xadmin import site, ModelXadmin """ 註冊 """ site.register(Book, BookConfig)