Django admin組件源碼流程

 admin 組件

  Django 自帶的用戶後臺組件javascript

  用於用戶便攜的操做html

admin 組件核心

  • 啓動
  • 註冊
  • 設計url

啓動核心代碼

  每一個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)

URL 分發核心代碼

  調用 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 組件的功能

"""
本身實現一個 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)
相關文章
相關標籤/搜索