通常创建一个Django项目的时候,在Django的配置文件settings.py中,都会有下面的这段配置:

INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'app01.apps.App01Config',
]

这段配置文件是Django用来注册所创建的应用的.

例如这里在创建Django项目时,添加了一个名为"app01"的应用.

在所创建的项目中,存在着一个名为"apps.py"的文件,这个文件的内容如下:

    from django.apps import AppConfig

    class App01Config(AppConfig):
name = 'app01'

在这个文件中,以所注册的应用名加"Config"定义的类中,其实还有一个方法:

    from django.apps import AppConfig

    class App01Config(AppConfig):
name = 'app01' def ready(self):
pass

这个ready是程序在执行路由映射之前执行这个方法.那这个函数有什么用呢??

在admin.py文件中,可以注册数据库中数据表,这样方便在Django的后台管理所注册的数据库.

admin.site.register(models.UserInfo)

把models.py中的类注册在这里后,就会生成在后台进行管理这个数据表的四个URL.

/admin/app01/userinfo/
/admin/app01/userinfo/add/
/admin/app01/userinfo/1/change/
/admin/app01/userinfo/2/delete/

实际上,把想在Django后台管理的数据表写在admin.py文件中以后,Django会执行一个autodiscover_modules方法.

def autodiscover():
autodiscover_modules('admin', register_to=site)

Django执行autodiscover_modules后,admin.py文件也就会执行了.

只有admin.py文件执行过后,Django的路由中生成在Django的后台中对已注册的数据表进行增删查改的路由关系映射.

admin执行后,又会执行site函数.

site又会执行什么样的操作呢??进入site函数,在sites.py文件的最后一行,可以看到:

site = AdminSite()

site是AdminSite这个类的一个单例模式.这样一来,执行site方法就相当于执行了AdminSite这个类中的__init__方法.

def __init__(self, name='admin'):
self._registry = {}
self.name = name
self._actions = {'delete_selected': actions.delete_selected}
self._global_actions = self._actions.copy()
all_sites.add(self)

执行admin.site方法就相当于实例化一个AdminSite对象,然后这个对象会调用AdminSite这个类中的register方法.

    def register(self, model_or_iterable, admin_class=None, **options):

        if not admin_class:
admin_class = ModelAdmin if isinstance(model_or_iterable, ModelBase):
model_or_iterable = [model_or_iterable]
for model in model_or_iterable:
if model._meta.abstract:
raise ImproperlyConfigured(
'The model %s is abstract, so it cannot be registered with admin.' % model.__name__
) if model in self._registry:
raise AlreadyRegistered('The model %s is already registered' % model.__name__) if not model._meta.swapped: if options: options['__module__'] = __name__
admin_class = type("%sAdmin" % model.__name__, (admin_class,), options) self._registry[model] = admin_class(model, self)

register方法的前两个参数都是一个类名.

可以看到register方法的最后会把其参数定义的类加入到__init__方法中_registry方法定义的那个空字典中.

同时对参数中的类进行实例化.

类进行实例化的参数为这个类本身以及site本身.类似下面的情形,

    {
models.UserInfo: UserInfoAdmin(models.UserInfo,site对象),
models.UserGroup: ModelAdmin(models.UserGroup,site对象),
}

同时,由于对AdminSite进行实例化的时候使用了单例模式,所以程序第一次执行完后,系统中会一直存在这个site对象.

这样一来,admin.py程序后,就相当于是把在admin.py中注册的类以及对应的配置文件实例化之后的对象全部封装到AdminSite的register方法中了.

admin.py执行完成后,Django才开始执行urls.py中配置的路由关系映射.

urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^index/', index),
]

如上所示,在路由关系映射中,Django也会再执行一次admin.site.urls的方法.

进入urls方法中,可以看到

@property
def urls(self):
return self.get_urls(), 'admin', self.name

urls方法是执行了一个get_urls方法.再次进入get_urls方法

    def get_urls(self):
from django.conf.urls import url, include ... 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

在get_urls方法中,循环_registry这个字典,为字典中的每个类生成Django后台使用的增删查改等操作的url.

urlpatterns += [
url(r'^%s/%s/' % (model._meta.app_label, model._meta.model_name), include(model_admin.urls)),
]

在这里,

* model._meta.app_label     表示的是Django中添加的应用名
* model._meta.model_name 表示Django的数据库中的表名

把这两个字符串以"/"进行拼接后生成新的字符串

urlpatterns与这个字符串进行拼接,生成了新的urlpatterns.

在这一行的后边,model_admin又会调用这个对象中的url函数间接执行get_url方法来生成路由关系映射的后半部分.

这个生成的后半部分路由再与前面的新urlpatterns进行拼接,依次循环就生成在Django后台进行数据表操作的路由关系映射.

综上所述,在admin.py中注册models.py中的类的流程

1. 先执行admin.py,使用单例模式创建一个admin.site的对象
2. 在admin.site对象中,把admin.py中定义的类全部注册,并把类中所有的配置全部传递到admin.site对象的_registry生成的字典中
3. 在生成url时,url会循环site中的类,为每一个类生成相应的url

这就是在admin.py中注册数据表后Django的执行流程.

Django的admin.py注册流程的更多相关文章

  1. Django 中 admin 的执行流程

    Django 中 admin 的执行流程 1 循环加载执行所有已经注册的 app 中的 admin.py 文件 def autodiscover(): autodiscover_modules('ad ...

  2. django在admin后台注册自己创建的数据库表

    django在admin后台注册自己创建的数据库表,这样我们就可以在admin后台看到表结构信息,我们就可以在admin后台快速录入表记录信息 如果没有注册,那么你在登录django自带的admin的 ...

  3. django python manage.py runserver 流程

    python manage.py runserver 流程分析 版本 python27 django 1.0 搭建可运行的环境 创建python27 虚拟环境 github 下载 django-1.0 ...

  4. django的admin后台注册model并显示

    在admin后台注册model并显示其他字段: 修改app下的admin.py,注册model: from .models import vmadmin.site.register(vm) #注册名为 ...

  5. 如何给django admin.py配置超级管理员?注册表格?

    admin.py是django给我们提供的功能非常强大的后台,况且支持拓展,,如果你要是觉得admin的后台不够牛逼你可以自己写一个!如何自己写一个后台,后面我有时间了会给大家更新!一起学习!一起进步 ...

  6. django之admin流程

    admin 类复习: class Base(object): def __init__(self,val): self.val = val def func(self): self.test() pr ...

  7. stark组件之注册【模仿Django的admin】

    一.先看下django的admin是如何实现注册功能 首先导入admin这个对象和我们的model模块 from django.contrib import admin # Register your ...

  8. 第三百零六节,Django框架,models.py模块,数据库操作——创建表、数据类型、索引、admin后台,补充Django目录说明以及全局配置文件配置

    Django框架,models.py模块,数据库操作——创建表.数据类型.索引.admin后台,补充Django目录说明以及全局配置文件配置 数据库配置 django默认支持sqlite,mysql, ...

  9. 四 Django框架,models.py模块,数据库操作——创建表、数据类型、索引、admin后台,补充Django目录说明以及全局配置文件配置

    Django框架,models.py模块,数据库操作——创建表.数据类型.索引.admin后台,补充Django目录说明以及全局配置文件配置 数据库配置 django默认支持sqlite,mysql, ...

随机推荐

  1. 【JavaScript_DOM 淘宝购物车】

    让我们一起看一下淘宝的购物车是怎么做的吧,刚刚入门的我可能很多地方的用法都不够优化,不过个人感觉先把逻辑清晰之后再做的话其实也并不难哦, 以下是我做的页面代码: HTML代码: <!DOCTYP ...

  2. 洛谷 P1553 数字反转(升级版)【字符串+STL stack】

    P1553 数字反转(升级版) 题目描述 给定一个数,请将该数各个位上数字反转得到一个新数. 这次与NOIp2011普及组第一题不同的是:这个数可以是小数,分数,百分数,整数.整数反转是将所有数位对调 ...

  3. 基于Windows环境下cmd/编译器无法输入中文,显示中文乱码解决方案

    基于Windows环境下cmd/编译器无法输入中文,显示中文乱码解决方案 两个月前做C++课设的时候,电脑编译器编译结果出现了中文乱码,寻求了百度和大神们,都没有解决这个问题,百度上一堆解释是对编译器 ...

  4. UESTC 1599 wtmsb【优先队列+排序】

    题目链接:UESTC 1599 wtmsb 题意:给你一组数,每一次取出两个最小的数,将这两个数的和放入这组数中,直到这组数只剩下一个,求最后剩下那个数的大小! 分析:比赛的时候首先我就看到这道题数据 ...

  5. [bzoj3702] 二叉树

    一个节点的儿子是否交换,不会影响到它和兄弟节点间的逆序对数. 所以每次合并线段树的时候算一下交换与不交换的逆序对数,然后选个较小值就行了. #include<cstdio> #includ ...

  6. Gym100814B Gym100814F Gym100814I(异或) ACM International Collegiate Programming Contest, Egyptian Collegiate Programming Contest (2015) Arab Academy for Science and Technology

    今日份的训练题解,今天写出来的题没有昨天多,可能是因为有些事吧... Gym100814B 这个题就是老师改卷子,忘带标准答案了,但是他改了一部分卷子,并且确定自己改的卷子没出错,他想从改过的卷子里把 ...

  7. HDU6237-A Simple Stone Game-找素因子(欧拉函数)-2017中国大学生程序设计竞赛-哈尔滨站-重现赛

    A Simple Stone Game Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 262144/262144 K (Java/Ot ...

  8. linphone-android-客户端APP-工程解读

    LinphoneLauncherActivity 是APP的入口组件,在这个组件里,它会启动LinphoneService这个后台服务,然后不断地判断这个后台服务是否已经启动完毕,如果已经启动完毕后, ...

  9. spring如何控制事务

    Spring 的事务,可以说是 Spring AOP 的一种实现. AOP面向切面编程,即在不修改源代码的情况下,对原有功能进行扩展,通过代理类来对具体类进行操作. spring是一个容器,通过spr ...

  10. java中强,软,弱,虚引用 以及WeakHahMap

    java中强,软,弱,虚引用  以及WeakHahMap   一:强软引用: 参考:http://zhangjunhd.blog.51cto.com/113473/53092/进行分析   packa ...