CMDB - ModelForm

CMDB  -  ModelForm

当我们写的页面越来越多,需要的增删改查查的页面就会成倍增长。
为了解决这个重复搬无用砖的问题,
在django 的admin源码理由,就有一个可以套用复写的方法
自动发现功能
在urls.py里
admin自带的一个源码

urlpatterns = [
    url(r'^admin/', admin.site.urls),  # admin.site.urls 这是源码入口
]

manage.py
django对象网络编程时用到了一个socket套接字文件
就是 wsgi
socket -> wsgi (里面封装了一个HTTP协议)

启动顺序
admin - > 自定义的V1模块 ->url
每当我们启动django 时
会自动去发现模板里要拼接的url 成一个字典
当要访问某个类时,
自动去渲染它相对的增删改查查的页面

class AryaSite(object):

    def __init__(self):
        self._registry = {}

    def register(self, model_class, model_config):
                     # 这是model ORM类  # 这是个类,model_config
        self._registry[model_class] = model_config(model_class, self)


    def urls(self):
        parttents = [
                url('^login/', init.login),
                url('^logout/', init.logout),
                url('^register/', init.register),
              ]
        for model_class, model_config in self._registry.itmes():
            JG = "^{0}/{1}/".format(model_class._meta.app_label, model_class._meta.model_name)
                                   # model_class._meta.app_label 是 当前所在目录的目录名字
                                   # model_class._meta.model_name  指向对象的ORM 的类名
            pt = url(JG, model_config.urls)  #这个 urls 是谁?
            parttents.append(pt)
        return parttents


site = AryaConfig()

admin 自动发现

form xxxx improt models   # 数据表 

admin.site.register(models.Lable)   # 用admin注册,吧ORM 的类注册进去
admin.site.register(models.Host)
admin.site.register(models.Disk)
admin.site.register(models.Os)

同理
使用自定义的v1模块 来模仿 admin注册 自动发现

water.py

class LableConfig(v1.AryaConfig):   #注册 去找父类的 AryaConfig 的init方法
    list_display = ['name'] 

v1.site.register(models.Lable, LableConfig)  # 实例化对象
     #  register传入 ORM类名,   注册的类

v1.py

class AryaConfig(object):
    def __init__(self, model_class, site):   # model_class = model_class , site = AryaSite
        self.model_class=model_class    # ->  ORM 类名
        self.app=self.model_class._meta.app_label
        self.mod=self.model_class._meta.model_name
        self.site=site                  # 每个 site 的对象

    @property  # 这个装饰器,是为了不加括号就能执行
    def urls(self):
        parttents = [
            url('^$', self.list,name='%s_%s_list' %(self.app,self.mod)),  # 定义了需要的增删改查查 页面
            url('list.html', self.list,name='%s_%s_list' %(self.app,self.mod)),
            url('^add.html', self.add,name='%s_%s_add' %(self.app,self.mod)),
            url('^(\d+)/delete.html', self.delete,name='%s_%s_del' %(self.app,self.mod)),
            url('^(\d+)/update.html', self.change,name='%s_%s_edit' %(self.app,self.mod)),
              ]
        # parttents+=self.gouzi()
        return parttents,None,None  #实际上 返回多个值时,自动转成元组,系统自动加上括号

自动发现功能

autodiscover

在django 启动时,会自动加载settings.py
所有应用的 admin 也会被加载

settings.py

from django.contrib import admin  # admin 里面有 __init__方法
from django.contrib.admin.apps import AdminConfig

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
            ]

源码
from django.contrib import admin
导入包时,会自动执行init.py 文件
init.py

from django.utils.module_loading import autodiscover_modules

def autodiscover():   # 源码自带 自动发现功能,我们可以利用这个方法来套用到自己的应用里
    autodiscover_modules('admin', register_to=site)
                # 'admin'源码最好别改

default_app_config = 'django.contrib.admin.apps.AdminConfig'
   # 关键字符串,通过反向切割可以取值再用反射,可以使用form xxx import xxx 导入模块

源码
admin/apps.py

from django.apps import AppConfig

class AdminConfig(SimpleAdminConfig):
    """The default AppConfig for admin which does autodiscovery."""

    def ready(self):
        super(AdminConfig, self).ready()
        self.module.autodiscover()  
        # 不难发现,在这个位置他调用上面封装的自动发现类
        #这里的是对象的module 调用的自动发现功能
        # 通过他的父类去找到他的初始化传值方法 -> AppConfig

源码
apps/config.py

class AppConfig(object):
    """
    Class representing a Django application and its configuration.
    """

    def __init__(self, app_name, app_module):
        # Full Python path to the application eg. 'django.contrib.admin'.
        self.name = app_name

        # Root module for the application eg. <module 'django.contrib.admin'
        # from 'django/contrib/admin/__init__.pyc'>.
        self.module = app_module  
        # 这是初始化传入的是,对象的值,就是上面源码传入的admin值
        ......

在我们创建APP 的时候, 系统会自动创建几个文件
其中里面有一个文件,几乎被我们忽略的
他们都继承了 AppConfig
from django.apps import AppConfig
它就自动的到了那个自动发现的功能
可以利用这点,将我们自己写的模板,让系统自动发现
apps.py

from django.apps import AppConfig   

class App01Config(AppConfig):
    name = 'app01'

改写成

from django.apps import AppConfig  # AppConfig  导入不变

from django.utils.module_loading import autodiscover_modules  
# 将autodiscover_modules模块导入
# 导入包时,会自动执行它的__init__.py文件

class XxxConfig(AppConfig):
    name = 'xxx'
    def ready(self):    # 将ready方法吸入,并在函数体里加载方法
        autodiscover_modules('xxx')   
        # 'xxx'  对应自己创建的应用名

Python 内存优化机制

第一次的导入,是真的导入,
第二次或者第N次的导入,是导入第一次的缓存

a.py

class Aa(object):
    def __init__(self):
        print('aaaaaaaa')

aaa = Aa()

b.py

from a import aaa
bbb=1

c.py

from a import aaa
ccc =1

run.py

from a import aaa
from b import bbb
from c import ccc



 结果 ->  aaaaaaaa

# 这样只会导入一次的print 结果

未完待续。。。。。。。。。。。。。。。。
posted @ 2019-04-23 18:14  H·c  阅读(166)  评论(0编辑  收藏  举报