django-admin的源码流程

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 )
            

原文地址:https://www.cnblogs.com/maaosheng/p/11621446.html

时间: 2024-07-31 02:41:55

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

Django学习【第29篇】:django-admin的源码流程

django-admin的源码流程 一.admin的源码流程 首先可以确定的是:路由关系一定对应一个视图函数 a.当点击运行的时候,会先找到每一个app中的admin.py文件,并执行 b.执行urls.py admin.site是什么? admin.site,urls    返回的是一个元组,里面的第一个元素是一个列表 django-admin的源码流程 我们自己生成的动态的访问url ====================================初级版===============

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

版本 新建一个工程Myproject和一个app名为api (1)api/models.py from django.db import models class UserInfo(models.Model): USER_TYPE = ( (1,'普通用户'), (2,'VIP'), (3,'SVIP') ) user_type = models.IntegerField(choices=USER_TYPE) username = models.CharField(max_length=32,u

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

一.简介 在上一篇博客中已经介绍了django rest framework 对于认证的源码流程,以及实现过程,当用户经过认证之后下一步就是涉及到权限的问题.比如订单的业务只能VIP才能查看,所以这时候需要对权限进行控制.下面将介绍DRF的权限控制源码剖析. 二.基本使用 这里继续使用之前的示例,加入相应的权限,这里先介绍使用示例,然后在分析权限源码 1.在django 项目下新建立目录utils,并建立permissions.py,添加权限控制: class MyPremission(obje

Django rest framework源码分析(一) 认证

一.基础 最近正好有机会去写一些可视化的东西,就想着前后端分离,想使用django rest framework写一些,顺便复习一下django rest framework的知识,只是顺便哦,好吧.我承认我是故意的,因为我始终觉得,如果好的技术服务于企业,顺便的提高一下自己.大家都很开心不是不.再次强调一下,真的只是顺便. 安装吧 pip install djangorestframework 1.2.需要先了解的一些知识 理解下面两个知识点非常重要,django-rest-framework

Django Rest Framework源码剖析(三)-----频率控制

一.简介 承接上篇文章Django Rest Framework源码剖析(二)-----权限,当服务的接口被频繁调用,导致资源紧张怎么办呢?当然或许有很多解决办法,比如:负载均衡.提高服务器配置.通过代理限制访问频率等,但是django rest framework自身就提供了访问频率的控制,可以从代码本身做控制. 二.频率控制内部原理概述 django rest framework 中频率控制基本原理基于访问次数和时间,通过计算实现,当然我们也可以自己定义频率控制方法.基本原理如下: 启用频率

Django Rest Framework源码剖析(八)-----视图与路由

一.简介 django rest framework 给我们带来了很多组件,除了认证.权限.序列化...其中一个重要组件就是视图,一般视图是和路由配合使用,这种方式给我们提供了更灵活的使用方法,对于使用者而言不同的视图具有不同的功能,这样我们可以根据需求定制自己视图.以下是官网传送门:http://www.django-rest-framework.org/api-guide/views/ 在之前的文章中,由于参杂了权限.认证等(如果不了解请看博客的以前的文章),但在本章中基本可以不使用,所进使

rest_framework-02-权限-内置权限源码流程

权限 问题:不同视图不同权限可以访问 1.models.py from django.db import models class UserInfo(models.Model): user_type_choices = ( (1,'普通用户'), (2,'VIP'), (3,'SVIP'), ) user_type = models.IntegerField(choices=user_type_choices) # username = models.CharField(max_length=3

onLayout源码 流程 思路详解(ANDROID自定义视图)

简介: 在自定义view的时候,其实很简单,只需要知道3步骤: 1.测量--onMeasure():决定View的大小 2.布局--onLayout():决定View在ViewGroup中的位置 3.绘制--onDraw():如何绘制这个View. 而第3步的onDraw系统已经封装的很好了,基本不用我们来操心,只需要专注到1,2两个步骤就中好了. 第一步的测量,可以参考我之前的文章:(ANDROID自定义视图--onMeasure流程,MeasureSpec详解) 而这篇文章就来谈谈第二步:"

Django搭建及源码分析(三)---+uWSGI+nginx

每个框架或者应用都是为了解决某些问题才出现旦生的,没有一个事物是可以解决所有问题的.如果觉得某个框架或者应用使用很不方便,那么很有可能就是你没有将其使用到正确的地方,没有按开发者的设计初衷来使用它,当你将一个框架的优势使用到极致时一定是非常舒服和顺手的一件事.但同时也有可能衍生另一个问题,这个框架只解决了你的问题一,没有解决问题二.三等等,因此,就出现了多个框架/应用相结合的情况.比如Django + uWSGI + nginx. 本人初学python,找了一些实例进行了一些操作,以下纯属目前的