django-admin的源码流程
一、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的源码流程的更多相关文章
- Django admin组件源码流程
admin 组件 Django 自带的用户后台组件 用于用户便携的操作 admin 组件核心 启动 注册 设计url 启动核心代码 每个app 通过 apps.py 扫描 admin.py 文件 并执 ...
- Django rest_framework 认证源码流程
一.请求到来后,都要先执行dispatch方法 dispatch根据请求方式的不同触发get/post/put/delete等方法 注意,APIView中的dispatch方法有很多的功能 def d ...
- Django Rest Framework框架源码流程
在详细说django-rest-framework源码流程之前,先要知道什么是RESTFUL.REST API . RESTFUL是所有Web应用都应该遵守的架构设计指导原则. REST是Repres ...
- Django session 源码流程
流程 Django session源码流程 首先执行的是SessionMiddleware的init方法 import_module(settings.SESSION_ENGINE) 导入了一个 dj ...
- Django drf:序列化增删改查、局部与全局钩子源码流程、认证源码分析、执行流程
一.序列化类的增.删.改.查 用drf的序列化组件 -定义一个类继承class BookSerializer(serializers.Serializer): -写字段,如果不指定source ...
- Django rest framework源码分析(4)----版本
版本 新建一个工程Myproject和一个app名为api (1)api/models.py from django.db import models class UserInfo(models.Mo ...
- Django rest framework源码分析(1)----认证
目录 Django rest framework(1)----认证 Django rest framework(2)----权限 Django rest framework(3)----节流 Djan ...
- Django rest framework源码分析(2)----权限
目录 Django rest framework(1)----认证 Django rest framework(2)----权限 Django rest framework(3)----节流 Djan ...
- Django REST framework 源码剖析
前言 Django REST framework is a powerful and flexible toolkit for building Web APIs. 本文由浅入深的引入Django R ...
随机推荐
- Kaldi阅读并更改代码
Common utilities base/kaldi-common.h 几乎所有Kaldi程序都会include该头文件. 该头文件include了一些其他位于base/目录的头文件,主要提供: 错 ...
- Java -cp 命令行引用多个jar包的简单写法(Windows、Linux
1.Windows下用法 在Windows上,可以使用 用法:java your-jar-lib-folder/* your-main-class your-jar-lib-folder为存放一堆ja ...
- 【译】第九篇 SQL Server安全透明数据加密
本篇文章是SQL Server安全系列的第九篇,详细内容请参考原文. Relational databases are used in an amazing variety of applicatio ...
- pythonのsqlalchemy外键关联查询
#!/usr/bin/env python import sqlalchemy from sqlalchemy import create_engine from sqlalchemy.ext.dec ...
- Java strictfp有什么作用
- Latex 问题解决
1. 当bib文件中包含待引用的参考文献,并且在tex中正常通过\cite{}引用,却依然提示citation undefined,pdf中显示问号时,怎么解决报错. 解决:删除根目录下的 .bbl ...
- jquery知识巩固
1.jquery中的index方法和eq方法 index()方法:index()获取的索引值是相对同兄弟元素,即同一个父元素,,所以首先要确认一下这个元素的兄弟是谁,例如: 当遇到以上的情况很容易就觉 ...
- liunx 安装Zabbix的心酸历程
作者:邓聪聪 为了工作之需要,在系统服务方面不断的摸爬打滚,有了这样点点滴滴的经验,留后在使用! 插件网盘取. 链接: https://pan.baidu.com/s/1i5u0ed3 密码: rx ...
- HTTP笔记01-http相关的基础知识
这个系列文章是阅读<图解HTTP>后写下的笔记 当我们在浏览器输入url,点击回车后,浏览器显示我们需要的web页面,那么,这个界面是如何产生的? 根据浏览器地址中输入的url,浏览器从相 ...
- boost 实现http断点续传
// testc.cpp : Defines the entry point for the console application. // #include "stdafx.h" ...