解析admin的源码
第一步:项目启动,加载settings文件中的 INSTALLED_APPS
里边有几个app就加载几个,按照注册顺序来执行。
第二步:其中加载的是admin.py,加载每一个app下的admin.py文件
第三步:执行代码
第四步:看admin.site走的流程
咱走一下源码
总结一下:
第五步:执行register方法
admin.site.register(Book, BookAdmin)
admin.site.register(Publish)
class ModelAdmin(BaseModelAdmin):pass def register(self, model_or_iterable, admin_class=None, **options): if not admin_class: admin_class = ModelAdmin # Instantiate the admin class to save in the registry self._registry[model] = admin_class(model, self)
注册就结束了!
补充一下:
在每一个app的admin .py中加上
print(admin.site._registry) # 执行结果?
app01:
app02:
第六步:admin的URL配置
urlpatterns = [ url(r'^admin/', admin.site.urls), ]
class AdminSite(object): def get_urls(self): from django.conf.urls import url, include urlpatterns = [] # Add in each model's views, and create a list of valid URLS for the # app_index valid_app_labels = [] 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) return urlpatterns @property def urls(self): return self.get_urls(), 'admin', self.name
总结admin源码解析:
1:在Django项目启动时,加载settings中的install_apps,扫描每个APP项目下的admin.py文件的文件, 创建admin.site中的对象,site = AdminSite(),本质实例化一个对象,以后不管谁来调用都使用这个对象, 执行对象的register方法,目的将注册类添加到_register中, admin.site是一个对象(单例模式创建),其中封装了_register。 2:再次调用admin.site的urls属性。 返回了一个元组,元组有三个元素,self.get_urls(),'admin ',self.name。 第一个元素是一个函数返回的是一个列表,列表中是url,是循环admin.site中的_register(ruanzhiste), 中的注册类,生成url,放在列表中。为每个注册类生成一级URL,其次调用类的样式对象下的get_url_func(self) 函数,生成二级URL,同时为每一个增删改查URL创建别名,用于反向解析,每个url对应一个视图函数。