最新免费视频:www.pythonav.com (冒着被砍死的风险)

admin

 

 

执行顺序 : Admin

 

  1. 执行admin.py,导入models

第一次进来的时候,先创建admin.site对象(如果下次再有引入,不会重新创建)

  • admin. site. regi slte r(models. Role) 
admin. site. regi ster(models. Userlnfo) 
admin. site. regi ster(models. UserType)
  1. 拿到对象后执行该对象下的register()方法
    • 目的是将 注册的类 添加到_registry{}中
  1. admin.site是实例化AdminSite的对象
  1. 实例化完成后,执行__init__方法
    • def (self, name='admin'): 
self._registry = {} # model_class class -> admin_class instance 
self 
. name = name 
self ._actions 
= {'delete_selected': actions. delete_selected} 
self. 
—global_actions 
= self ._actions.copyO 
all_sites .add(self)
  2. 拿到一个_registry = {}
    1. 再看AdminSite类下的register()方法,里面执行的是啥?
      • def 
register(self, model_or_iterabZe, admin_cZass=None, **options): 
(Reqister the given model(s) with the given admin class.. 
if not admin_class: 
admin_class 
= ModelAdmin 
if isinstance(modeZ_or_iterable, 
Model Base) 
model_or_iterable 
% model . _ name_ 
for model in model_or_iterable: 
if model ._meta. abstract: 
raise ImproperlyConfigured( 
'The model %s is abstract, 
if model in self._registry: 
so it cannot be registered with 
raise AlreadyRegistered( 'The model %s is already registered' 
admin. ' 
model. _ 
name
    1. register()可以传进两个参数,第二个参数默认为None
      • 如果我们自己定义了一个RoleConfig(admin.ModelAdmin):类, 它会优先调用自定义的类.
      • - class RoleConfig(admin.Mode1Admin): 
list_display 
= C'id' , 'caption'] 
admin. site. regi ster(models. Role , RoleConfid) 
admin. site. regi ster(models. Userlnfo) 
admin. site. regi ster(models. UserType)

 

 

  • 调用register后.会传进去一个_registry
  • 你注册一个它就会在_registry里面生成一个键值对
  • _registry = {

models.Role : ModelAdmin(models.Role,admin.site),

}

  • _registry = {

models.Role : RoleConfig(models.Role,admin.site),

}    // 它会调用内部的一个 list_display

 

  • _ registry 
models. Role: ModelAdminCmodels.R01e,admin.site), 
models. Userlnfo: ModelAdmin(models.UserInfo,admin.site) 
models. UserType: ModelAdmin(mode1s.UserType,admin.site)
  • 咱们综上所有都是为了生成 _registry 这个字典

 

 

=====================================================================================

 

接下来,通过我们访问admin 可以看到. 

  1. 注册过的每一张表,都生成若干张表.在这里咱们默认为 增删改查四张表
  • 请求过来后,咱们应该执行视图.
  • 当运行程序时,
    1. 会先找到每一个APP中的admin.py文件,并加载(记得要注册哦)
    2. 创建admin.site中的对象,执行register方法.

 

 

  1. 接下来来到urls,在此处执行如图.   再次调用admin.site的urls
  • urlpatterns 
path( ' admin/' , 
admin. site. urls) ,
    1. 这个urls看起来是个属性对不对.  别急…给你图
    • @property 
def Prls(self): 
return self. 
' admin' , 
self 
. name
    • 看到@property没
    • 伪造成属性,其实它的本质是个方法哦
    1. 看它的返回值,三个参数用逗号隔开.  它其实就是返回了一个元组.
      • 该元组下,有三个参数,第一个参数是个函数. 我们点进去看看
      • def 
include, 
r s import 
path, re_path 
# Since this module gets imported in the application's root package, 
# it cannot import models from other applications at the module level, 
# and django.contrib. contenttypes.views imports ContentType. 
from django. contrib. contenttypes 
import 
views 
as contenttype_views 
def wrap(vi ew, cacheable=FaZse): 
def wrapper( *args, : 
self. cacheable)(*args, 
return 
wrapper. admin_site = self 
return update_wrapper(wrapper, 
vi ew) 
# Admin-site-wide views. 
urlpatterns 
* * kwargs) 
valid_app_ 
for model, 
del_admin 
in self._registry. items(): 
if valid_app abets: 
regex = 
urlpatter C 
re_pa (regex, 
return urlpatterns 
wrap(self. app_ 
i ndex 
name='app_list'),

 

  • 由此可见, 第一个元素返回了一个列表
    • 手动展示一下
    • urlpatterns 
url(r'Aadmin/I 
admin. site.urls) , 
url( r' Alogin/$' , login, 
name= login'), 
url(rIAff/I, 
(url_list ,None, None,
  1. 接下来我们来看看这个列表是个啥?🌚🌚🌚
    • # Admtn-stte-wtde vtews. 
urlpatterns 
wrap(self. index), name=' index ' ) , 
path(' ' 
path('login/' , self. login, 
' login 
name= 
path( 'logout/' , wrap(self. logout), name='logout 
path( ' password_change/' , wrap(self.password_change, 
cacheabl True) , 
name= 
' password_change ' ) , 
path( 
password_change/done/' , 
wrap(sel f. password_change_done , 
cacheabl True) , 
password_change_done' , 
narne= 
path(' jsi18n/' , wrap(se1f.i18n_javascript, 
cacheabl True) , 
path( 
' r/<int : content_type_id>/<path : object_id>/' , 
wrap(contenttype_views. shortcut) , 
narne= ' vi ew_on_site' , 
name= 
'jsi18n'),

 

  1. 来, 看完这个urlpatterns是什么之后,咱在这个get_urls()里面继续看
    • valid_app_labels 
for model, model_admin in self. _ registry. items(): 
urlpatterns += C 
path( '%s/%s/' % (model model ._meta.model_name) 
if model ._meta. app_label 
not in valid_app_labels: 
val i s. append(model . _meta. app_label) 
if valid_app_labels: 
' . join(valid_app_labels) + ')/$' 
regex = + 
urlpatterns += C 
re_path(regex, 
wrap(self .app_index), name=' app_list'), 
return urlpatterns 
i ncl . urls))

 

  • 这里可以看到, 在咱们拿到的那个字典里面,疯狂循环对不对.
  • 为每一个类生成url

 

  • 这个就是他的前缀 (应用名,类名)
    • 观察这个图的最后,有个include(model_admin.urls),有没有觉得很眼熟,可是又有点不对劲…
    • 咱们之前执行过一次admin.site.urls, 这里又来了个model_admin.urls
    • 什么鬼???  莫急…   我们点进去瞅瞅先
      • @property 
def urls(self): 
return self
      • 这里的urls 是 ModelAdmin类下的方法哦,可不能混淆
        • 再进去看看这里的get_urls()是什么
        • def 
from django.urls import path 
def wrap(view): 
def **kwargs): 
self. admin_site. admin_vi ew(vi ew) args , 
return 
wrapper. model_admin 
= self 
vi ew) 
return update_wrapper(wrapper, 
* kwargs) 
info = self.model self .model ._meta.model_name 
urlpatterns 
path( ' 
wrap(self.changelist_view), narne='%s_%s_changelist' % info), 
path('add/' , wrap(self.add_view), name='%s_%s_add' % info), 
path('autocomplete/' , wrap(self.autocomplete_view), name='%s_%s_autocomplete' % info), 
path('<path:object_id>/history/' , wrap(self.history_view), name='%s_%s_history' % info), 
path('<path:object_id>/delete/' , wrap(self. delete_view), name='%s_%s_delete' % info), 
path('<path:object_id>/change/' , wrap(self. change_view), name='%s_%s_change' % info), 
# For backwards compatibility (was the change url before 1.9) 
path( ' , wrap(RedirectView.as_view( 
pattern_name='%s:%s_%s_change' % (Cself.admin_site.name,) + info) 
return urlpatterns
        • 是的, 增删改查!!!

 

总结 :   django admin url生成的本质!!!  

  • 读取_regstry 字典里面的数据,为字典里的每一个类,生成了四个url

posted @ 2017-12-14 01:09  uuuuuuu  阅读(146)  评论(0编辑  收藏  举报

最新免费视频:www.pythonav.com (冒着被砍死的风险)