一、admin的源码流程

首先可以确定的是:路由关系一定对应一个视图函数

a、当点击运行的时候,会先找到每一个app中的admin.py文件,并执行

b、执行urls.py

admin.site是什么?

admin.site,urls    返回的是一个元组,里面的第一个元素是一个列表

django-admin的源码流程
我们自己生成的动态的访问url
====================================初级版=========================
from django.shortcuts import HttpResponse
from django.conf.urls import url
from django.contrib import admin
from app01 import views
def login(request):
return HttpResponse("ok") url_list = [] for model_class,v in admin.site._registry.items():
print(model_class) #打印的是每一个类<class 'app01.models.UserInfo'>
cls_name = model_class._meta.model_name #当前类名称的小写
app_name = model_class._meta.app_label #当前app的名称
val = url(r'^{0}/{1}/$'.format(app_name,cls_name), login, name="login")
url_list.append(val) urlpatterns = [
url(r'^admin/', admin.site.urls),
# admin.site这个对象里面有一个属性_registry = {}
#点击urls查看源码返回的是一个元组,元组的第一个元素是一个列表
url(r'^index/', ([
url(r'^app01/userinfo/$', login,name="login"),
url(r'^app01/roles/$', login,name="login"),
],None,None)), url(r'^index2/', (url_list,None,None,)), #吧上面定义的列表拿下来,这是后就动态生成了
]
================================升级============================
路径http://127.0.0.1:8001/index/app01/roles/后面还有增删改查的路径
http://127.0.0.1:8001/index/app01/roles/add/
http://127.0.0.1:8001/index/app01/roles/1/change/
http://127.0.0.1:8001/index/app01/roles/1/del/ 实现流程
from django.shortcuts import HttpResponse
from django.conf.urls import url
from django.contrib import admin
from app01 import views
def login(request):
return HttpResponse("ok") def change_list(request):
return HttpResponse("列表页面") def add_view(request):
return HttpResponse("添加页面") def change_view(request,nid):
return HttpResponse("修改页面") def delete_view(request,nid):
return HttpResponse("删除页面") url_list = [] for model_class,v in admin.site._registry.items():
print(model_class) #打印的是每一个类<class 'app01.models.UserInfo'>
cls_name = model_class._meta.model_name #当前类名称的小写
app_name = model_class._meta.app_label #当前app的名称
urls_list = url(r'^{0}/{1}/$'.format(app_name,cls_name), change_list, name="login")
url_list.append(urls_list) add_url = url(r'^{0}/{1}/add/$'.format(app_name, cls_name), add_view, name="login")
url_list.append(add_url) change_url = url(r'^{0}/{1}/(\d+)/change/$'.format(app_name, cls_name), change_view, name="login")
url_list.append(change_url) del_url = url(r'^{0}/{1}/(\d+)/del/$'.format(app_name, cls_name), delete_view, name="login")
url_list.append(del_url) urlpatterns = [
url(r'^admin/', admin.site.urls),
# admin.site这个对象里面有一个属性_registry = {}
#点击urls查看源码返回的是一个元组,元组的第一个元素是一个列表
url(r'^index/', (
[
url(r'^app01/userinfo/$', login,name="login"),
url(r'^app01/roles/$', login,name="login"),
],None,None)),
url(r'^index2/', (url_list,None,None,)), #吧上面定义的列表拿下来,这是后就动态生成了
] 说明了:
url的本质:它读取_registry所有字典里面的数据,为字典里面的每一个类生成了4个url
==================================修改上面的版本=============================
定义了一个
def get_urls():
temp = [
url(r'^$'.format(app_name, cls_name), change_list),
url(r'^add/$'.format(app_name, cls_name), add_view),
url(r'^del/$'.format(app_name, cls_name), delete_view),
url(r'^change/$'.format(app_name, cls_name), change_view)
]
return temp url_list = []
for model_class,v in admin.site._registry.items():
print('-------',model_class) #打印的是每一个类<class 'app01.models.UserInfo'>
cls_name = model_class._meta.model_name #当前类名称的小写
app_name = model_class._meta.app_label #当前app的名称
方式一:
# all_urls = url(r'^{0}/{1}/'.format(app_name,cls_name), (get_urls(),None,None,))
方式二:
all_urls = url(r'^{0}/{1}/'.format(app_name,cls_name), include(get_urls()) )
url_list.append(all_urls) urlpatterns = [
url(r'^admin/', admin.site.urls),
# admin.site这个对象里面有一个属性_registry = {}
#点击urls查看源码返回的是一个元组,元组的第一个元素是一个列表
url(r'^index/', (
[
url(r'^app01/userinfo/', ([
url(r'^$', change_list, name="login"),
url(r'^add/$', add_view, name="login"),
url(r'^(\d+)/del/$', delete_view, name="login"),
url(r'^(\d+)/change/$', change_view, name="login"),
],None,None),name="login"),
url(r'^app01/usertype/', ([
url(r'^$', change_list, name="login"),
url(r'^add/$', add_view, name="login"),
url(r'^(\d+)/del/$', delete_view, name="login"),
url(r'^(\d+)/change/$', change_view, name="login"),
], None, None), name="login"),],None,None)),
url(r'^app02/article/', ([
url(r'^$', change_list, name="login"),
url(r'^add/$', add_view, name="login"),
url(r'^(\d+)/del/$', delete_view, name="login"),
url(r'^(\d+)/change/$', change_view, name="login"),
],None,None),name="login"), # index和index2的两个是一样的,我们可以用index2的方式替代index
url(r'^index2/', (url_list,None,None,)), #吧上面定义的列表拿下来,这是后就动态生成了
] include的本质就是:返回了一个元组,元组的第一个是这个模块
include里面
既可以写一个列表include([]),利用include做分发
也可以返回一个字符串:帮我们去找到这个模块,找到所有的映射关系 include(model_admin.urls)
model_admin是什么?ModelAdmin对象的urls

总结

- admin源码流程
a. 运行程序,找到每一个app中的 admin.py 文件,并加载
- app01.admin.py
- 创建admin.site中的对象
- 执行对象的 register方法,目的:将注册类添加到 _registry中
_registry = {
key是传进来的model value:是ModelAdmin的对象,传了两个参数
models.Role: ModelAdmin(models.Role,admin.site),
models.UserInfo: ModelAdmin(models.UserInfo,admin.site)
models.UserType: ModelAdmin(models.UserType,admin.site)
} - app02.admin.py
- 用app01.admin中创建那个admin.site对象
- 执行对象的 register方法,目的:讲注册类添加到 _registry中
_registry = {
models.Role: ModelAdmin(models.Role,admin.site),
models.UserInfo: ModelAdmin(models.UserInfo,admin.site)
models.UserType: ModelAdmin(models.UserType,admin.site)
models.Article: ModelAdmin(models.Article,admin.site)
} admin.site是一个对象(单例模式创建),其中封装了:
_registry = {
models.Role: ModelAdmin(models.Role,admin.site),
models.UserInfo: ModelAdmin(models.UserInfo,admin.site)
models.UserType: ModelAdmin(models.UserType,admin.site)
models.Article: ModelAdmin(models.Article,admin.site)
}
b. urls.py
再次调用 admin.site 对象的 urls属性:
urlpatterns = [
url(r'^admin/', admin.site.urls),
] class ModelAdmin(object):
def __init__(self,model_class,site):
self.model_class = model_class
self.site = site def changelist_view(self,request):
data_list = self.model_class.objects.all() #是动态的
return HttpResponse('列表页面') def add_view(self,request):
return HttpResponse('添加页面') def delete_view(self,request,nid):
return HttpResponse('删除页面') def change_view(self,request,nid):
return HttpResponse('修改页面') def get_urls(self):
urlpatterns = [
url(r'^$', self.changelist_view),
url(r'^add/$', self.add_view),
url(r'^(.+)/delete/$', self.delete_view),
url(r'^(.+)/change/$', self.change_view),
]
return urlpatterns @property
def urls(self):
return self.get_urls() class AdminSite(object):
def __init__(self):
self._registry = {} def register(self,model_class,model_admin):
self._registry[model_class] = model_admin(model_class,self) def get_urls(self):
"""
models.Role: ModelAdmin(models.Role,admin.site),
models.UserInfo: ModelAdmin(models.UserInfo,admin.site)
models.UserType: ModelAdmin(models.UserType,admin.site)
models.Article: ModelAdmin(models.Article,admin.site)
"""
url_list = []
for model_class,model_admin in self._registry.items():
model_class是一个类
app_name = model_class._meta.app_label
model_name = model_class._meta.model_name
url_list += [
url('%s/%s' %(app_name,model_name,), include(model_admin.urls))
] return url_list @property
def urls(self):
return (self.get_urls(), None,None )

django-admin的源码流程的更多相关文章

  1. Django admin组件源码流程

    admin 组件 Django 自带的用户后台组件 用于用户便携的操作 admin 组件核心 启动 注册 设计url 启动核心代码 每个app 通过 apps.py 扫描 admin.py 文件 并执 ...

  2. Django rest_framework 认证源码流程

    一.请求到来后,都要先执行dispatch方法 dispatch根据请求方式的不同触发get/post/put/delete等方法 注意,APIView中的dispatch方法有很多的功能 def d ...

  3. Django Rest Framework框架源码流程

    在详细说django-rest-framework源码流程之前,先要知道什么是RESTFUL.REST API . RESTFUL是所有Web应用都应该遵守的架构设计指导原则. REST是Repres ...

  4. Django session 源码流程

    流程 Django session源码流程 首先执行的是SessionMiddleware的init方法 import_module(settings.SESSION_ENGINE) 导入了一个 dj ...

  5. Django drf:序列化增删改查、局部与全局钩子源码流程、认证源码分析、执行流程

    一.序列化类的增.删.改.查 用drf的序列化组件   -定义一个类继承class BookSerializer(serializers.Serializer):   -写字段,如果不指定source ...

  6. Django rest framework源码分析(4)----版本

    版本 新建一个工程Myproject和一个app名为api (1)api/models.py from django.db import models class UserInfo(models.Mo ...

  7. Django rest framework源码分析(1)----认证

    目录 Django rest framework(1)----认证 Django rest framework(2)----权限 Django rest framework(3)----节流 Djan ...

  8. Django rest framework源码分析(2)----权限

    目录 Django rest framework(1)----认证 Django rest framework(2)----权限 Django rest framework(3)----节流 Djan ...

  9. Django REST framework 源码剖析

    前言 Django REST framework is a powerful and flexible toolkit for building Web APIs. 本文由浅入深的引入Django R ...

随机推荐

  1. linux 添加并格式化新硬盘

    linux挂载磁盘1. 格式化磁盘mkfs -t ext4 /dev/sdb2. 挂载mount /dev/xvdb /home3. 查看磁盘对应的uuidblkid4. 加入开机自动挂载,在/etc ...

  2. centos 查找命令的可用包/命令属于哪个软件包

    centos 查找命令的可用包 yum provides */commond 例如: yum provides */lsb_release

  3. 第20月第17天 mvvm 多次点击push -ObjC

    1. 响应式库EasyReact建成后,为了能使其得到更好的利用,更好地降低使用的理解和学习成本,臧成威老师又带领团队开发了基于响应式的MVVM框架:EasyMVVM. https://www.jia ...

  4. 将本地时间转换成 UTC 时间,0时区时间

    // 将时间戳转换成日期格式: function timestampToTime(timestamp) { var date = new Date(timestamp);//时间戳为10位需*1000 ...

  5. 【mmall】递归查询子节点并排重

    代码 @Override public ServerResponse getSelfAndChildrenCategory(Integer categoryId) { if (categoryId ! ...

  6. tcp黏包

    转载https://www.cnblogs.com/wade-luffy/p/6165671.html 无论是服务端还是客户端,当我们读取或者发送消息的时候,都需要考虑TCP底层的粘包/拆包机制. 回 ...

  7. es教程

    概念 关系数据库 ⇒ 数据库 ⇒ 表 ⇒ 行 ⇒ 列(Columns) Elasticsearch ⇒ 索引(Index) ⇒ 类型(type) ⇒ 文档(Docments) ⇒ 字段(Fields) ...

  8. gradle文件中自定义字段值在java代码中使用

    1. 在build.gradle 中  buildConfigField  的参数有3个 第一个类型 第二个为名称 第三个是值 如果是字符串类型 请不要忘记 双引号! buildTypes {     ...

  9. Typecho反序列化导致前台 getshell 漏洞复现

    Typecho反序列化导致前台 getshell 漏洞复现 漏洞描述: Typecho是一款快速建博客的程序,外观简洁,应用广泛.这次的漏洞通过install.php安装程序页面的反序列化函数,造成了 ...

  10. Keepalived两节点出现双VIP情况及解决方法【原创】

    1.故障现象 俩台服务器keepalived的vip在俩台服务器同时出现 A:10.70.12.72 B:10.70.12.73 2.问题分析 1).先分析那台服务器在提供服务 A:10.70.12. ...