zoukankan      html  css  js  c++  java
  • 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</span><span style="color: #800000;">'</span><span style="color: #800000;">^index2/</span><span style="color: #800000;">'</span>, (url_list,None,None,)),  <span style="color: #008000;">#</span><span style="color: #008000;">吧上面定义的列表拿下来,这是后就动态生成了</span>
    

    ]

    复制代码
    复制代码
    ================================升级============================
    路径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 </span>= url(r<span style="color: #800000;">'</span><span style="color: #800000;">^{0}/{1}/add/$</span><span style="color: #800000;">'</span>.format(app_name, cls_name), add_view, name=<span style="color: #800000;">"</span><span style="color: #800000;">login</span><span style="color: #800000;">"</span><span style="color: #000000;">)
    url_list.append(add_url)
    
    change_url </span>= url(r<span style="color: #800000;">'</span><span style="color: #800000;">^{0}/{1}/(d+)/change/$</span><span style="color: #800000;">'</span>.format(app_name, cls_name), change_view, name=<span style="color: #800000;">"</span><span style="color: #800000;">login</span><span style="color: #800000;">"</span><span style="color: #000000;">)
    url_list.append(change_url)
    
    del_url </span>= url(r<span style="color: #800000;">'</span><span style="color: #800000;">^{0}/{1}/(d+)/del/$</span><span style="color: #800000;">'</span>.format(app_name, cls_name), delete_view, name=<span style="color: #800000;">"</span><span style="color: #800000;">login</span><span style="color: #800000;">"</span><span style="color: #000000;">)
    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"),

    </span><span style="color: #008000;">#</span><span style="color: #008000;"> index和index2的两个是一样的,我们可以用index2的方式替代index</span>
    url(r<span style="color: #800000;">'</span><span style="color: #800000;">^index2/</span><span style="color: #800000;">'</span>, (url_list,None,None,)),  <span style="color: #008000;">#</span><span style="color: #008000;">吧上面定义的列表拿下来,这是后就动态生成了</span>
    

    ]

    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)
                        }
    
            </span>-<span style="color: #000000;"> app02.admin.py
                </span>-<span style="color: #000000;"> 用app01.admin中创建那个admin.site对象
                </span>-<span style="color: #000000;"> 执行对象的 register方法,目的:讲注册类添加到 _registry中 
                    _registry </span>=<span style="color: #000000;"> {
                        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 </span>=<span style="color: #000000;"> {
                    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 </span>=<span style="color: #000000;"> [
                    url(r</span><span style="color: #800000;">'</span><span style="color: #800000;">^admin/</span><span style="color: #800000;">'</span><span style="color: #000000;">, admin.site.urls),
                ]
            
            </span><span style="color: #0000ff;">class</span><span style="color: #000000;"> ModelAdmin(object):
                </span><span style="color: #0000ff;">def</span> <span style="color: #800080;">__init__</span><span style="color: #000000;">(self,model_class,site):
                    self.model_class </span>=<span style="color: #000000;"> model_class
                    self.site </span>=<span style="color: #000000;"> site 
                    
                </span><span style="color: #0000ff;">def</span><span style="color: #000000;"> changelist_view(self,request):
                    data_list </span>= self.model_class.objects.all()   <span style="color: #008000;">#</span><span style="color: #008000;">是动态的</span>
                    <span style="color: #0000ff;">return</span> HttpResponse(<span style="color: #800000;">'</span><span style="color: #800000;">列表页面</span><span style="color: #800000;">'</span><span style="color: #000000;">)
    
                </span><span style="color: #0000ff;">def</span><span style="color: #000000;"> add_view(self,request):
                    </span><span style="color: #0000ff;">return</span> HttpResponse(<span style="color: #800000;">'</span><span style="color: #800000;">添加页面</span><span style="color: #800000;">'</span><span style="color: #000000;">)
    
    
                </span><span style="color: #0000ff;">def</span><span style="color: #000000;"> delete_view(self,request,nid):
                    </span><span style="color: #0000ff;">return</span> HttpResponse(<span style="color: #800000;">'</span><span style="color: #800000;">删除页面</span><span style="color: #800000;">'</span><span style="color: #000000;">)
    
                </span><span style="color: #0000ff;">def</span><span style="color: #000000;"> change_view(self,request,nid):
                    </span><span style="color: #0000ff;">return</span> HttpResponse(<span style="color: #800000;">'</span><span style="color: #800000;">修改页面</span><span style="color: #800000;">'</span><span style="color: #000000;">)
                
                </span><span style="color: #0000ff;">def</span><span style="color: #000000;"> get_urls(self):
                     urlpatterns </span>=<span style="color: #000000;"> [
                        url(r</span><span style="color: #800000;">'</span><span style="color: #800000;">^$</span><span style="color: #800000;">'</span><span style="color: #000000;">, self.changelist_view),
                        url(r</span><span style="color: #800000;">'</span><span style="color: #800000;">^add/$</span><span style="color: #800000;">'</span><span style="color: #000000;">, self.add_view),
                        url(r</span><span style="color: #800000;">'</span><span style="color: #800000;">^(.+)/delete/$</span><span style="color: #800000;">'</span><span style="color: #000000;">, self.delete_view),
                        url(r</span><span style="color: #800000;">'</span><span style="color: #800000;">^(.+)/change/$</span><span style="color: #800000;">'</span><span style="color: #000000;">, self.change_view),
                    ]
                    </span><span style="color: #0000ff;">return</span><span style="color: #000000;"> urlpatterns
                
                @property 
                </span><span style="color: #0000ff;">def</span><span style="color: #000000;"> urls(self):
                    </span><span style="color: #0000ff;">return</span><span style="color: #000000;"> self.get_urls()
                
            
            </span><span style="color: #0000ff;">class</span><span style="color: #000000;"> AdminSite(object):
                </span><span style="color: #0000ff;">def</span> <span style="color: #800080;">__init__</span><span style="color: #000000;">(self):
                    self._registry </span>=<span style="color: #000000;"> {}
                    
                </span><span style="color: #0000ff;">def</span><span style="color: #000000;"> register(self,model_class,model_admin):
                    self._registry[model_class] </span>=<span style="color: #000000;"> model_admin(model_class,self)
                
                </span><span style="color: #0000ff;">def</span><span style="color: #000000;"> get_urls(self):
                    </span><span style="color: #800000;">"""</span><span style="color: #800000;">
                    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)
                    </span><span style="color: #800000;">"""</span><span style="color: #000000;">
                    url_list </span>=<span style="color: #000000;"> []
                    </span><span style="color: #0000ff;">for</span> model_class,model_admin <span style="color: #0000ff;">in</span><span style="color: #000000;"> self._registry.items():
                        model_class是一个类
                        app_name </span>=<span style="color: #000000;"> model_class._meta.app_label
                        model_name </span>=<span style="color: #000000;"> model_class._meta.model_name 
                        url_list </span>+=<span style="color: #000000;"> [
                            url(</span><span style="color: #800000;">'</span><span style="color: #800000;">%s/%s</span><span style="color: #800000;">'</span> %<span style="color: #000000;">(app_name,model_name,), include(model_admin.urls))
                        ]
                        
                    </span><span style="color: #0000ff;">return</span><span style="color: #000000;"> url_list
                        
                
                @property
                </span><span style="color: #0000ff;">def</span><span style="color: #000000;"> urls(self):
                    </span><span style="color: #0000ff;">return</span><span style="color: #000000;"> (self.get_urls(), None,None )
            </span></pre>
    
    复制代码
  • 相关阅读:
    多进程之数据安全问题
    windows 下安装 RabbitMQ
    springCloud Config分布式配置中心
    git配置ssh
    spring cloud Gateway 新一代网关
    spring cloud Hystrix 断路器
    spring cloud OpenFeign 服务接口调用
    Ribbon负载均衡服务调用
    consul服务注册与发现
    Eureka服务治理
  • 原文地址:https://www.cnblogs.com/maaosheng/p/11621446.html
Copyright © 2011-2022 走看看