一、admin的源码流程

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

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

settings---->INSTALLED_APPS------>admin

#加载每个app下面的admin.py文件
def autodiscover():autodiscover_modules('admin', register_to=site)

注册:

admin/sites.py

#admin.site : 单例对象
class AdminSite():def __init__(self, name='admin'):self._registry = {}def register(self, model, admin_class=None, **options):if not admin_class:admin_class = ModelAdminself._registry[model] = admin_class(model, self)# site._registry:{模型类:该模型类的配置类对象,........}site = AdminSite() 

app01/admin.py:

from django.contrib import adminadmin.site.register(Book)    #  site._registry:{Book:ModelAdmin(Book)}
admin.site.register(Publish) #  site._registry:{Book:ModelAdmin(Book),Publish:ModelAdmin(Publish)} 

c、执行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 tempurl_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的方式替代indexurl(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_classself.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_labelmodel_name = model_class._meta.model_name url_list += [url('%s/%s' %(app_name,model_name,), include(model_admin.urls))]return url_list@propertydef urls(self):return (self.get_urls(), None,None )

转载于:https://www.cnblogs.com/guoyunlong666/p/9204183.html

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. 1月24日学习内容整理:Django的admin组件源码分析及流程

    一.单例模式 单例模式(Singleton Pattern)是一种常用的软件设计模式,该模式的主要目的是确保某一个类只有一个实例存在.当你希望在整个系统中,某个类只能出现一个实例时,单例对象就能派上用 ...

  4. Django Rest Framework源码剖析(二)-----权限

    一.简介 在上一篇博客中已经介绍了django rest framework 对于认证的源码流程,以及实现过程,当用户经过认证之后下一步就是涉及到权限的问题.比如订单的业务只能VIP才能查看,所以这时 ...

  5. 【武sir】django rest framework源码和实战_day01(上)

    (0)摘要 # 课程链接 4天搞定django rest framework源码和实战_哔哩哔哩_bilibili # 课程内容 (1)内容概要_略 (2)内容回顾_略 (3)django 视图之 C ...

  6. android 虚拟按键源码流程分析

    android 虚拟按键流程分析 今天来说说android 的虚拟按键的源码流程.大家都知道,android 系统的状态栏,虚拟按键,下拉菜单,以及通知显示,keyguard 锁屏都是在framewo ...

  7. SpringSecurity详细介绍RememberMe源码流程

      本文我们来详细看看rememberMe的源码流程 rememberMe源码分析   首先我们要搞清楚rememberMe功能应该是在认证成功后才能具有的,所以我们应该从Usernamepasswo ...

  8. MediaPlayer源码流程简要分析

    涉及文件目录: \frameworks\base\media\java\android\media\MediaPlayer.java \frameworks\base\media\jni\androi ...

  9. Dubbo负载均衡的源码流程(2022.5.30)

    Dubbo负载均衡的源码流程 1.默认负载均衡策略:RandomLoadBalance(随机策略) 2.负载均衡策略存在以下五种: 2.1 RandomLoadBalance(随机) 2.2 Roun ...

最新文章

  1. mysql 5.7 xbackup_CentOS 7 下 MySQL 5.7 配置 Percona Xtrabackup
  2. 精美的电路图都是怎么画出来的?
  3. java 继承 注解_在java中实现组合注解原理分析(注解继承)
  4. 【django】类视图
  5. android自动回复退订,Android实现短信自动回复,挂电话
  6. 交叉编译iperf源代码
  7. java 线程 wait 一定要同步_java中使用wait就得使用同步锁,而且2个线程必须都使用同步代码块,否则就会异常...
  8. 弱鸡儿长乐爆零旅Day3
  9. 适用于openvino 2020.2的yolov5的docker制作
  10. html input 字体颜色_HTML常用标签汇总
  11. 【转】Netty那点事(一)概述
  12. Python模块 - itertools循环器模块
  13. t3-财务通计算机名称,用友T3用友通财务软件操作方法
  14. oracle宿舍管理系统实训报告,学生宿舍管理系统_开题报告
  15. [教程] KGFMapSystem - 快速创建游戏中的迷你地图
  16. android 神气插件 自动补全tabnine
  17. css + js实现简单无缝滚动字幕
  18. echarts数据可视化项目经验积累
  19. RNN识别PTB数据代码精解
  20. 阿里巴巴B2B测试用例编写规范

热门文章

  1. centos arm-linux-gcc,CentOS 5.5下arm-linux-gcc交叉编译环境的搭建
  2. python提取日志内容_Python正则提取日志内容
  3. python打开文件夹中的tiff_浅谈python下tiff图像的读取和保存方法
  4. ❤️作为测试行业的过来人,宝贵的经验分享给刚入行的你
  5. 蓝桥杯泊松分酒java_【蓝桥杯】泊松分酒
  6. 计算机科学导论_[计算机科学导论]第一章:计算机学什么
  7. 掌业宝服务器维护升级,奇游联机宝APP焕新升级 主机加速多设备各享最优区服...
  8. Installing SuiteSparse
  9. install opencv on mac and use it in xcode
  10. BB-UNet:带有包围框先验的U-Net