Django的admin.py注册流程
通常创建一个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注册流程的更多相关文章
- Django 中 admin 的执行流程
Django 中 admin 的执行流程 1 循环加载执行所有已经注册的 app 中的 admin.py 文件 def autodiscover(): autodiscover_modules('ad ...
- django在admin后台注册自己创建的数据库表
django在admin后台注册自己创建的数据库表,这样我们就可以在admin后台看到表结构信息,我们就可以在admin后台快速录入表记录信息 如果没有注册,那么你在登录django自带的admin的 ...
- django python manage.py runserver 流程
python manage.py runserver 流程分析 版本 python27 django 1.0 搭建可运行的环境 创建python27 虚拟环境 github 下载 django-1.0 ...
- django的admin后台注册model并显示
在admin后台注册model并显示其他字段: 修改app下的admin.py,注册model: from .models import vmadmin.site.register(vm) #注册名为 ...
- 如何给django admin.py配置超级管理员?注册表格?
admin.py是django给我们提供的功能非常强大的后台,况且支持拓展,,如果你要是觉得admin的后台不够牛逼你可以自己写一个!如何自己写一个后台,后面我有时间了会给大家更新!一起学习!一起进步 ...
- django之admin流程
admin 类复习: class Base(object): def __init__(self,val): self.val = val def func(self): self.test() pr ...
- stark组件之注册【模仿Django的admin】
一.先看下django的admin是如何实现注册功能 首先导入admin这个对象和我们的model模块 from django.contrib import admin # Register your ...
- 第三百零六节,Django框架,models.py模块,数据库操作——创建表、数据类型、索引、admin后台,补充Django目录说明以及全局配置文件配置
Django框架,models.py模块,数据库操作——创建表.数据类型.索引.admin后台,补充Django目录说明以及全局配置文件配置 数据库配置 django默认支持sqlite,mysql, ...
- 四 Django框架,models.py模块,数据库操作——创建表、数据类型、索引、admin后台,补充Django目录说明以及全局配置文件配置
Django框架,models.py模块,数据库操作——创建表.数据类型.索引.admin后台,补充Django目录说明以及全局配置文件配置 数据库配置 django默认支持sqlite,mysql, ...
随机推荐
- SQL数据开发(经典) 基本操作
数据开发(经典) 1.按姓氏笔画排序: Select * From TableName Order By CustomerName Collate Chinese_PRC_Str oke_ci_as ...
- SPRINGBOOT 读书笔记
Spring基础 Spring的发展 xml配置 注解配置 Java配置 Spring模块:核心容器 AOP 消息 web 数据访问集成 常用的:@Component @Service @Reposi ...
- [51nod1443]路径和树
给定一幅无向带权连通图G = (V, E) (这里V是点集,E是边集).从点u开始的最短路径树是这样一幅图G1 = (V, E1),其中E1是E的子集,并且在G1中,u到所有其它点的最短路径与他在G中 ...
- hdu_1031_结构体排序
题目很好理解,将列求和,取前k大的 我的代码思路:对列求和,后取出前k大的id加入结果数组,对比后面和第k大相同的评分id也加入到结果数组,最后对结果数组排序 代码: #include<cstd ...
- python程序的标准输入输出
1, A+B Problem : http://acm.sdut.edu.cn/sdutoj/problem.php?action=showproblem&problemid=1000 #! ...
- HDU 2544 最短路(模板题——Floyd算法)
题目: 在每年的校赛里,所有进入决赛的同学都会获得一件很漂亮的t-shirt.但是每当我们的工作人员把上百件的衣服从商店运回到赛场的时候,却是非常累的!所以现在他们想要寻找最短的从商店到赛场的路线,你 ...
- TP5使用phpmailer实现邮件发送
1.从github下载PHPMailer,在vendor目录中新建文件夹phpmailer,将压缩包中的class.phpmailer.php和class.smtp.php复制到phpmailer中, ...
- javascript中window.location.search的用法和作用。
用该属性获取页面 URL 地址: window.location 对象所包含的属性 属性 描述 hash 从井号 (#) 开始的 URL(锚) host 主机名和当前 URL 的端口号 hostnam ...
- 通读cheerio API ——NodeJs中的jquery
通读cheerio API ——NodeJs中的jquery 所谓工欲善其事,必先利其器,所以通读了cheerio的API,顺便翻译了一遍,有些地方因为知道的比较少,不知道什么意思,保留了英文,希望各 ...
- QTP10破解方法及mgn-mqt82.exe下载
经试验可以成功安装license,具体步骤如下:一.从HP官方网上下载QTP10.0并安装.二.安装成功后,在C:\Program Files\Common Files\Mercury Interac ...