Django学习【第29篇】: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/kcwxx/p/10156584.html

时间: 2024-10-31 10:03:03

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

Django REST framework之解析器实例以及源码流程分析

解析器 我们都知道源生Django默认只能解析content-type:application/x-www-form-urlencoded头格式的,若果是json格式,form-data格式都要自己处理. 但是在restframework已经为我们做好了,只要配置上,就能帮我们解析请求的数据 举例说明: 表设计: 1 from django.db import models 2 3 4 class UserGroup(models.Model): 5 title = models.CharFie

WebRTC学习之 Intel&#174; Collaboration Suite for WebRTC源码流程解读

年后回来,因为新项目的需求,开始了解WebRTC相关的知识.目前接触的是Intel? Collaboration Suite for WebRTC.刚开始看SDK发现很多概念是我目前不知道的,于是恶补了一周基本的网络相关的知识.再来看Demo和Jar包里面的源码,对其代码逻辑的理解更深一步了.下面从代码层面分模块对Demo的设计和使用进行总结: 首先声明一下核心的类对象: private ConferenceClient mRoom; 无论是登录还是发布.订阅Stream,我们都需要mRoom来

Django学习笔记(四)—— Admin

疯狂的暑假学习之  Django学习笔记(四)-- Admin 参考:<The Django Book> 第6章 Django 可以使用admin自动创建管理界面. 1. 配置 django-admin.py startproject 创建的项目,如果没有注解掉默认的配置,python manage.py syncdb 创建用户后,直接 http://xxxxxx/admin 输入密码即可进入. 如果修改了配置文件,保证将 django.contrib.admin 加入setting.py 中

Django的View(视图)、settings源码的解析、模板层

一.FBV与CBV 视图函数并不只是指函数,也可以是类 FBV:基于函数的视图,类似面向函数式编程 CBV:基于类的视图,类似面向对象编程 研究解析render源码: render:返回html页面:并且能够给该页面传值 分析:FBV视图原理 from django.shortcuts import render,HttpResponse # Create your views here. from django.template import Template,Context # FBV解析

第三篇:白话tornado源码之请求来了

上一篇<白话tornado源码之待请求阶段>中介绍了tornado框架在客户端请求之前所做的准备(下图1.2部分),本质上就是创建了一个socket服务端,并进行了IP和端口的绑定,但是未执行 socket的accept方法,也就是未获取客户端请求信息. 概述 本篇就来详细介绍tornado服务器(socket服务端)是如何接收用户请求 数据以及如果根据用户请求的URL处理并返回数据,也就是上图的3系列所有步骤,如上图[start]是一个死循环,其中利用epoll监听服务端 socket句柄,

第五篇:白话tornado源码之褪去模板的外衣

上一篇<白话tornado源码之请求来了> 介绍了客户端请求在tornado框架中的生命周期,其本质就是利用epoll和socket来获取并处理请求.在上一篇的内容中,我们只是给客户端返回 了简单的字符串,如:“Hello World”,而在实际开发中,需要使用html文件的内容作为模板,然后将被处理后的数据(计算或数据库中的数据)嵌套在模板中,然后将嵌套了数据的 html文件的内容返回给请求者客户端,本篇就来详细的剖析模板处理的整个过程. 概述 上图是返回给用户一个html文件的整个流程,较

Django学习之配置篇

Django之路:安装与配置 MTV Model Template View 数据库 模版文件 业务处理 了解Django框架,功能齐全 一.安装Django&Django基本配置 安装Django pip3 django 配置Django 1.配置Django环境变量 D:\Program files\python37 D:\Program files\python37\Lib\site-packages\django\bin D:\Program files\python37\Scripts

django学习~第四篇

django表单   1  今天继续来学学django的表单       首先介绍下http的方法,这是最基本的       GET 方法 GET一般用于获取/查询 资源信息,以?分割URL和传输数据,多个参数用&连接,login.action?name=hyddd&password=idontknow&verify=%E4%BD%A0 %E5%A5%BD GET提交的数据会在地址栏中显示出来       POST 方法 而POST一般用于更新 资源信息 把提交的数据放置在是HTT

django学习~第五篇

一 简介:之前我们都是大概了解了下django本身和一些基本功能 这次我们深入一些聊        model模块 此处不考虑外键等特殊情况       今天来实现用户注册界面       1 常见的具体字段介绍            AutoField 自增列            CharField 字符类型            BooleanField 布尔类型            DateTimeField 日期类型           IntegerField 整型       2