博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Django admin组件源码流程
阅读量:6592 次
发布时间:2019-06-24

本文共 6408 字,大约阅读时间需要 21 分钟。

 admin 组件

  Django 自带的用户后台组件

  用于用户便携的操作

admin 组件核心

  • 启动
  • 注册
  • 设计url

启动核心代码

  每个app 通过 apps.py 扫描 admin.py 文件 并执行

"""setting.py setting.py 中会对注册的 app 自动加载各自里面的 AppxxConfig 模块""" INSTALLED_APPS = [    ...    'app01.apps.App01Config',    'app02.apps.App02Config',]
"""apps.pyapp下的里面的 adminConfig 在自动执行的时候可以进行启动操作"""from django.apps import AppConfigclass App01Config(AppConfig):    name = 'app01'
"""admin 源码 调用每个app 下的admin.py 文件进行执行"""import admin        # 执行每一个app下的admin.py文件        autodiscover_modules('admin', register_to=site)
"""admin.py被执行的 admin.py 文件"""from django.contrib import adminfrom rbac.models import *# Register your models here.

 注册核心代码

   在admin.py 文件中对表进行注册

  注册后的表要判断是否有自定义的配置文件

  若没有则使用默认的 Modeladmin

"""admin 注册流程核心源码"""class AdminSite(object):    def __init__(self,name="admin"):        # 定义一个空字典用于保存注册        self._registry={}            # 注册函数    # 需要有两个参数, 被注册的表 以及 是否有自定义的配置操作    def register(self, model, admin_class=None, **options):        # 首先对是否存在自定义配置操作进行判断        if not admin_class:            # 如果无自定义则用默认的            admin_class = Modeladmin        # 有自己的就用自己的        # 注意这里的键为类名而不是字符串         self._registry[model] = admin_class(model, self)             # {Book:ModelAdmin(Book),Publi sh:ModelAdmin(Publish)}# 进行实例化实现单例模式# 其他所有的程序中的 admin 通过引入,用的都是这个对象 site=AdminSite()
""" admin.py 中对表进行注册操作"""from django.contrib import adminfrom rbac.models import *# Register your models here.# 基于模块的单例模式从而实现所有的注册表都使用的同一个 admin.site 对象admin.site.register(User)admin.site.register(Role)admin.site.register(Permission)

URL 分发核心代码

  调用 urls() 方法

  然后继续调用 get_urls() 方法

     遍历所有注册表,进行URL 的拼接合成最后生成一个列表返回给 urls.py

   最终在urls.py 进行调用

"""urls.pyurls.py 中全部写成了一条 所有的结果都在调用 urls方法后拿到"""urlpatterns = [    url(r'^admin/', admin.site.urls),]
"""admin 设计url 核心"""class AdminSite(object):    def get_urls(self):        urlpatterns = [            url(r'^$', wrap(self.index), name='index'),            url(r'^login/$', self.login, name='login'),            url(r'^logout/$', wrap(self.logout), name='logout'),            url(r'^password_change/$', wrap(self.password_change, cacheable=True), name='password_change'),            url(r'^password_change/done/$', wrap(self.password_change_done, cacheable=True),                name='password_change_done'),            url(r'^jsi18n/$', wrap(self.i18n_javascript, cacheable=True), name='jsi18n'),            url(r'^r/(?P
\d+)/(?P
.+)/$', wrap(contenttype_views.shortcut), name='view_on_site'), ] valid_app_labels = [] # 遍历注册过的表,对每个表生成 相应的 url 进行链接起来 for model, model_admin in self._registry.items(): urlpatterns += [ url(r'^%s/%s/' % (model._meta.app_label, model._meta.model_name), include(model_admin.urls)), ] if model._meta.app_label not in valid_app_labels: valid_app_labels.append(model._meta.app_label) if valid_app_labels: regex = r'^(?P
' + '|'.join(valid_app_labels) + ')/$' urlpatterns += [ url(regex, wrap(self.app_index), name='app_list'), ] # 返回给urls 得出的 urls列表 # 所有的urls 保存在 urlpatterns列表里面 return urlpatterns # 调用 get_urls 获得全部的结果 def urls(self): # 给urls.py 返回回去 return self.get_urls(), 'admin', self.name 

ps:

  url 的设计和分发合成是什么时候完成?

  答案:

    在项目启动的时候就完成

    在表进行注册后,就已经生成了,而不是url来了再生成

    本质上 django 启动就已经是启动了文件,不然你的admin 单例从何而来

模拟完成一个 Xadmin 组件实现 admin 组件的功能

"""自己实现一个 Xadmin 模块来替换掉 admin  和 admin 一样需要       启动      注册      url 分发""""""启动"""# setting.py INSTALLED_APPS = [    ...    'Xadmin.apps.XadminConfig',    'app01.apps.App01Config',    'app02.apps.App02Config',]# apps.pyfrom django.apps import AppConfigfrom django.utils.module_loading import autodiscover_modules# Xadmin.pyclass XadminConfig(AppConfig):    name = 'Xadmin'    """    启动     """    def ready(self):        autodiscover_modules('Xadmin')class ModelXadmin(object):    def __init__(self,model,site):        self.model=model        self.site=site        """        url 分发    二级分发和视图函数放在 配置类里面    不放在 注册类里面的原因:        因为注册类 单例生成 导致所有的注册表的self里面无法区分出来彼此的 配置类        如果放在 配置类中 self 就是注册表自己对应的 配置类 根本拿不到想要的数据(比如 表 本身)        比如 在 配置类 中 self.model 就是那个表,(在init 中注册的都可以随便拿来用了)    """         def list_view(self, request):        print("self.model",self.model)        data_list=self.model.objects.all()        print("data_list",data_list)        return render(request, 'list_view.html',{
"data_list":data_list}) def add_view(self, request): return render(request, 'add_view.html') def change_view(self, request, id): return render(request, 'change_view.html') def delete_view(self, request, id): return render(request, 'delete_view.html') def get_urls2(self): temp = [] temp.append(url(r"^$", self.list_view)) temp.append(url(r"^add/$", self.add_view)) temp.append(url(r"^(\d+)/change/$", self.change_view)) temp.append(url(r"^(\d+)/delete/$", self.delete_view)) return temp @property def urls2(self): return self.get_urls2(), None, Noneclass XadminSite(object): def __init__(self,name="admin"): self._registry={}"""注册 """ def register(self, model, admin_class=None, **options): if not admin_class: admin_class = Modeladmin self._registry[model] = admin_class(model, self) """url 分发""" def get_urls(self): temp = [] for model, admin_class_obj in self._registry.items(): app_name = model._meta.app_label model_name = model._meta.model_name temp.append(url(r'^{0}/{1}/'.format(app_name, model_name), admin_class_obj.urls2), ) return temp @property def urls(self): return self.get_urls(),None,None site=XadminSite() # url.pyfrom Xadmin.service.Xadmin import siteurlpatterns = [ url(r'^admin/', admin.site.urls), url(r'^Xadmin/', site.urls),]"""其他的程序使用方式   和以往admin的方式基本一致""" """ 启动 """# setting.pyINSTALLED_APPS = [ ... 'app01.apps.App01Config', "app02.apps.App02Config"]# apps.pyfrom django.apps import AppConfigclass App01Config(AppConfig): name = 'app01'# Xadmin.pyfrom Xadmin.service.Xadmin import site, ModelXadmin """ 注册 """ site.register(Book, BookConfig)

 

转载于:https://www.cnblogs.com/shijieli/p/10169743.html

你可能感兴趣的文章
分享11个超棒的移动应用(mobile apps)开发解决方案
查看>>
C/C++获取文件大小
查看>>
深入理解Java内存模型(五)——锁
查看>>
Chalubo僵尸网络来袭 IOT设备或将受到DDoS攻击
查看>>
如何实现百万TPS?详解JMQ4的存储设计
查看>>
这么说吧,NIO很简单,其实就是个牛逼IO
查看>>
使用Python快速获取公众号文章定制电子书(二)
查看>>
iOS下JS与OC互相调用(七)--Cordova 基础
查看>>
Three.js 关于立方体贴图产生边缘锯齿问题
查看>>
Nacos v0.7.0:对接CMDB,实现基于标签的服务发现能力
查看>>
【开发问题记录①】关于滑动CollectionView时ContentSize变化的问题
查看>>
java中GC的基本概念
查看>>
building xxx gradle project info的解决办法
查看>>
在 CentOS 7 上搭建 Jenkins + Maven + Git 持续集成环境
查看>>
数据结构与算法 | Leetcode 19. Remove Nth Node From End of List
查看>>
[LeetCode] 862. Shortest Subarray with Sum at Least K
查看>>
【分享】终端命令工具 自动生成vue组件文件以及修改router.js
查看>>
[LeetCode] Student Attendance Record I
查看>>
PHP回顾之多进程编程
查看>>
spring boot + redis
查看>>