<div class="postBody">
<div id="cnblogs_post_body" class="blogpost-body">
admin.py
url.py
=
以上两个文件都引用的是django.contrib.admin.site中的方法,site是AdminSite实例化出来的一个对象,所以site调用的register方法和urls属性(方法被@property装饰器装饰)是AdminSite这个类中定义的
在源码AdminSite这个类的构造方法初始化定义了一个空字典 _registry={}
看源码中的admin.site.register函数如下
def register(self,model_or_iterable,admin_class=None,** Registers the given model(s) with the given admin The model(s) should be Model classes,not instances.
If an admin </span><span style="color: #0000ff;">class</span> isn<span style="color: #800000;">'</span><span style="color: #800000;">t given,it will use ModelAdmin (the default</span>
admin options). If keyword arguments are given -- e.g.,list_display --<span style="color: #000000;">
they</span><span style="color: #800000;">'</span><span style="color: #800000;">ll be applied as options to the admin class.</span>
<span style="color: #000000;">
If a model <span style="color: #0000ff;">is already registered,<span style="color: #0000ff;">this<span style="color: #000000;"> will raise AlreadyRegistered.
If a model </span><span style="color: #0000ff;">is</span> <span style="color: #0000ff;">abstract</span>,<span style="color: #0000ff;">this</span><span style="color: #000000;"> will raise ImproperlyConfigured.
</span><span style="color: #800000;">"""
<span style="color: #ff0000;"> if not admin_class:
admin_class = ModelAdmin
</span><span style="color: #0000ff;">if</span><span style="color: #000000;"> isinstance(model_or_iterable,ModelBase):
model_or_iterable </span>=<span style="color: #000000;"> [model_or_iterable]
</span><span style="color: #0000ff;">for</span> model <span style="color: #0000ff;">in</span><span style="color: #000000;"> model_or_iterable:
</span><span style="color: #0000ff;">if</span> model._meta.<span style="color: #0000ff;">abstract</span><span style="color: #000000;">:
raise ImproperlyConfigured(
</span><span style="color: #800000;">'</span><span style="color: #800000;">The model %s is abstract,so it cannot be registered with admin.</span><span style="color: #800000;">'</span> %<span style="color: #000000;"> model.__name__
)
</span><span style="color: #0000ff;">if</span> model <span style="color: #0000ff;">in</span><span style="color: #000000;"> self._registry:
raise AlreadyRegistered(</span><span style="color: #800000;">'</span><span style="color: #800000;">The model %s is already registered</span><span style="color: #800000;">'</span> %<span style="color: #000000;"> model.__name__)
# Ignore the registration </span><span style="color: #0000ff;">if</span><span style="color: #000000;"> the model has been
# swapped </span><span style="color: #0000ff;">out</span><span style="color: #000000;">.
</span><span style="color: #0000ff;">if</span><span style="color: #000000;"> not model._meta.swapped:
# If we got </span>**<span style="color: #000000;">options then dynamically construct a subclass of
# admin_class with those </span>**<span style="color: #000000;">options.
</span><span style="color: #0000ff;">if</span><span style="color: #000000;"> options:
# For reasons I don</span><span style="color: #800000;">'</span><span style="color: #800000;">t quite understand,without a __module__</span>
# the created <span style="color: #0000ff;">class</span> appears to <span style="color: #800000;">"</span><span style="color: #800000;">live</span><span style="color: #800000;">"</span> <span style="color: #0000ff;">in</span><span style="color: #000000;"> the wrong place,# which causes issues later on.
options[</span><span style="color: #800000;">'</span><span style="color: #800000;">__module__</span><span style="color: #800000;">'</span>] =<span style="color: #000000;"> __name__
admin_class </span>= type(<span style="color: #800000;">"</span><span style="color: #800000;">%sAdmin</span><span style="color: #800000;">"</span> %<span style="color: #000000;"> model.__name__,(admin_class,),options)
# Instantiate the admin </span><span style="color: #0000ff;">class</span> to save <span style="color: #0000ff;">in</span><span style="color: #000000;"> the registry
<span style="color: #ff0000;">self._registry[model] </span></span><span style="color: #ff0000;">= admin_class(model,self)</span></pre>
<div class="cnblogs_code_toolbar">
register函数第一个参数是注册的模块名称,第二个参数不传默认是None,但是实际使用的是ModelAdmin,ModelAdmin已模块名称作为参数实例化得到的对象作为 registry字典的value。简化如下:
def register(self,**=</span><span style="color: #0000ff;">for</span> model <span style="color: #0000ff;">in</span><span style="color: #000000;"> model_or_iterable:
.......
.......
self._registry[model] </span>= admin_class(model,self)</pre>
<div class="cnblogs_code_toolbar">
django.contrib.contenttypes import views def wrap(view,cacheable</span>=<span style="color: #000000;">False):
......
</span><span style="color: #0000ff;">return</span><span style="color: #000000;"> update_wrapper(wrapper,view)
# Admin</span>-site-<span style="color: #000000;">wide views.
urlpatterns </span>=<span style="color: #000000;"> [
url(r</span><span style="color: #800000;">'</span><span style="color: #800000;">^$</span><span style="color: #800000;">'</span>,wrap(self.index),name=<span style="color: #800000;">'</span><span style="color: #800000;">index</span><span style="color: #800000;">'</span><span style="color: #000000;">),url(r</span><span style="color: #800000;">'</span><span style="color: #800000;">^login/$</span><span style="color: #800000;">'</span>,self.login,name=<span style="color: #800000;">'</span><span style="color: #800000;">login</span><span style="color: #800000;">'</span><span style="color: #000000;">),url(r</span><span style="color: #800000;">'</span><span style="color: #800000;">^logout/$</span><span style="color: #800000;">'</span>,wrap(self.logout),name=<span style="color: #800000;">'</span><span style="color: #800000;">logout</span><span style="color: #800000;">'</span><span style="color: #000000;">),url(r</span><span style="color: #800000;">'</span><span style="color: #800000;">^password_change/$</span><span style="color: #800000;">'</span>,wrap(self.password_change,cacheable=True),name=<span style="color: #800000;">'</span><span style="color: #800000;">password_change</span><span style="color: #800000;">'</span><span style="color: #000000;">),......
]
valid_app_labels </span>=<span style="color: #000000;"> []
</span><span style="color: #0000ff;">for</span> model,model_admin <span style="color: #0000ff;">in</span><span style="color: #000000;"> self._registry.items():
urlpatterns </span>+=<span style="color: #000000;"> [
url(r</span><span style="color: #800000;">'</span><span style="color: #800000;">^%s/%s/</span><span style="color: #800000;">'</span> %<span style="color: #000000;"> (model._meta.app_label,model._meta.model_name),include(model_admin.urls)),]
</span><span style="color: #0000ff;">if</span> model._meta.app_label not <span style="color: #0000ff;">in</span><span style="color: #000000;"> valid_app_labels:
valid_app_labels.append(model._meta.app_label)
......
</span><span style="color: #0000ff;">return</span><span style="color: #000000;"> urlpatterns
@property
def urls(self):
<span style="color: #0000ff;">return self.get_urls(),<span style="color: #800000;">'<span style="color: #800000;">admin<span style="color: #800000;">',self.name #返回的是一个元组
<div class="cnblogs_code_toolbar">
首先urls是个函数被@property装饰器装饰为属性,
,如下
会根据下面的代码添加到urlpatterns中
model,model_admin += %
model_class._meta.app_label 代表model所在的模块名比如app01 model_class._meta.model_name 代表model对应的表的小写名,比如userinfo
这样就生成了/app01/userinfo/ 这样的url前缀。
后面调用的include(model_admins.urls) 中的model_admins.urls 即执行的是self._registry['UserInfo'].urls =====admin_class(model,self).urls=======admin_class这个类生成对象的urls属性【此时这个对象是UserInfo的对象,所以下面get_url函数中的self指的就是UserInfo的对象】======admin_class这个类的urls属性========= >ModelAdmin这个类的urls属性【】
def wrap(view):
def wrapper(</span>*args,**<span style="color: #000000;">kwargs):
</span><span style="color: #0000ff;">return</span> self.admin_site.admin_view(view)(*args,**<span style="color: #000000;">kwargs)
wrapper.model_admin </span>=<span style="color: #000000;"> self
</span><span style="color: #0000ff;">return</span><span style="color: #000000;"> update_wrapper(wrapper,view)
info </span>=<span style="color: #000000;"> self.model._meta.app_label,self.model._meta.model_name
<span style="color: #ff0000;"> urlpatterns <span style="color: #ff0000;">= [
url(r'^$',wrap(self.changelistview),name='%s%s_changelist' % info),url(r'^add/$',wrap(self.addview),name='%s%s_add' % info),# self代表的是UserInfo的对象
url(r'^(.+)/history/$',wrap(self.historyview),name='%s%s_history' % info),url(r'^(.+)/delete/$',wrap(self.deleteview),name='%s%s_delete' % info),url(r'^(.+)/change/$',wrap(self.changeview),name='%s%s_change' % info),# For backwards compatibility (was the change url before 1.9)
url(r'^(.+)/$',wrap(RedirectView.as_view(
patternname='%s:%s%s_change' % ((self.admin_site.name,) + info)
))),]
<span style="color: #0000ff;">return<span style="color: #000000;"> urlpatterns
@property
def urls(self):
<span style="color: #0000ff;">return self.get_urls()
<div class="cnblogs_code_toolbar">
同理,urls是个被@property装饰的属性,调用ModelAdmin类自身的get_urls函数的时候返回的即是,这样和上面形成的url路径拼接即可得到如下的效果
urlpatterns =,name= %,name= %,name= %,name= %,name= %= % ((self.admin_site.name,) +
当然也可以自定制ModelAdmin,如下
<span style="color: #0000ff;">class<span style="color: #000000;"> UserInfoModelAdmin(ModelAdmin): # 没有super 是这个类只定义了一个方法,没有继承其他的?还是继承了所有,只覆盖了这一个呢? # 自定义功能
def changelist_view(self,request,*args,**<span style="color: #000000;">kwargs):
<span style="color: #0000ff;">return HttpResponse(<span style="color: #800000;">'<span style="color: #800000;">用户列表<span style="color: #800000;">'<span style="color: #000000;">)
admin.site.register(models.UserInfo,UserInfoModelAdmin) <span style="color: #0000ff;">class<span style="color: #000000;"> UserTypeModelAdmin(ModelAdmin):
pass
admin.site.register(models.UserType,UserTypeModelAdmin)
<div class="cnblogs_code_toolbar">
继承自ModelAdmin,并重写了changelist_view 这个方法,父类 其他的继承了吗?==
所以上面这张register的方法可以如下理解:
在admin.site对象的 _registry ===/admin/app01/userinfo//admin/app01/userinfo/add//admin/app01/userinfo/(d+)/delete//admin/app01/userinfo/(d+)/change/=models.UserType: obj2 </span>=<span style="color: #000000;"> ModelAdmin(models.UserType,#obj2 和上面说的同理,代表的是UserType对象
</span>/admin/app01/usertype/<span style="color: #000000;"> obj2.changelist_view
</span>/admin/app01/usertype/add/<span style="color: #000000;"> obj2.add_view
</span>/admin/app01/usertype/(d+)/delete/<span style="color: #000000;"> obj2.delete_view
</span>/admin/app01/usertype/(d+)/change/<span style="color: #000000;"> obj2.change_view
self.model</span>=<span style="color: #000000;">models.UserType
}
<span style="color: #0000ff;">for model,model_admin <span style="color: #0000ff;">in<span style="color: #000000;"> self._registry.items():
urlpatterns +=<span style="color: #000000;"> [
url(r<span style="color: #800000;">'<span style="color: #800000;">^%s/%s/<span style="color: #800000;">' %<span style="color: #000000;"> (model._meta.app_label,url(r<span style="color: #800000;">'<span style="color: #800000;">^%s/%s/<span style="color: #800000;">' % (<span style="color: #800000;">'<span style="color: #800000;">app01<span style="color: #800000;">',<span style="color: #800000;">'<span style="color: #800000;">userinfo<span style="color: #800000;">'<span style="color: #000000;">),]
<div class="cnblogs_code_toolbar">
(编辑:李大同)
【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!
|