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 的时候, 系统会自动创建几个文件
其中里面有一个文件,几乎被我们忽略的
他们都继承了 AppConfigfrom 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 结果
未完待续。。。。。。。。。。。。。。。。