<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装饰器装饰为属性,