前情提要:
crm中的admin组件重写.
一:admin的autodiscover
作用:实现扫面该项目中的所有的admin
1:执行顺序->
按照注册的顺序执行
二:单例模式
1:普通案例的格式
该案例的内存地址不同,实例对象有自己的实例空间,
2:单例模式的应用
单例模式的内存地址相同,在python文件加载过程中.单例模式可以减少相同文件的缓存,
2>1 基于__new__的单例模式
2>2 基于模块的单例模式
python中特有的,模块导入多次只会实现一次
2>2>1基于上例子
新建一个文件,并创建一个类,
2>2>2 导入该报重命名
内存地址相同,即是单例模式,只要是同一个程序就是单例
三:注册功能
1: admin中应用单例模式
2:site.register的注册功能
2>1:在register源码中
class AdminSite方法__init__内创建了一个空字典,存放单例的内容
register方法中存放入口参数,model 和admin_class
其中
如果 admin_class =None
1 or 0 1
2 or 3 2
0 or 1 1
如果有值,则走admin_calss 即自定制, 如果没有值则,ModelAdmin
modelAdmin 为默认配置类
当注册时在字典中增加key,valuse
2>2 如果全部注册完了以后,可以尝试打印该字典
如只注册了3个
则会显示5个,因为系统自动注册了两个,auto 和group
启动下看看:::
2 >3 register方法
该方法 会循环的从字典中拿取key和values ,
key为model 即为表明
valuse为样式类,如果不填写则传入默认的
四:设置url APPEND_SLASH参数
默认效果
五:url的分发
1 :url中的分发
django自带的以调用属性的方式,显示,使用为使用了@properp ,使方法以属性的形式可以代用
2:样式:
path('路由/',([
path('text01/',text01),
path('text02/',text02),
],None,None))
3:运行顺序
4:效果:
5:url 路由的多级分发
就是把原视图方法的地方在进行一次路由分发
5>1 : 运行路线
5>2 :效果图
六:从新设计admin的url分发
1:设置url的分发
在原视图函数的位置上设置一个可执行函数,返回值为视图函数,或者视图函数分层
2:动态的为模型类创建增删改查url
2>1 通过刚才字典的进行进一步操作
3: 拿到注册的字典,进行操作
循环的从字典内拿出来 key 和values
注意:valuse 的值是分为 配置类,和默认配置类
4:给temp增加path路径
4>1:参照admin表的模式.
自定义明/app名字/表明/操作名
4>2: 通过model的模型类获取app名字和model(表名)
4:2>1 获取表名
4:2>2 获取app名
5: 最终一级效果图
:效果图:
六:二层分发:(固定增删改查)
1: 在一层分发后面再开一个分发函数,get_urls2()
2:函数内部,
增删改查,4个path
注意什么都不写,即默认为点开一层的效果,我们这里让他为查询界面
七:自己设计一个stark组件(自己写一个admin)
1:创建一个新的app :stark
2:把app注册到setting中
3:把启动命令加入到apps中
from django.apps import AppConfigfrom django.utils.module_loading import autodiscover_modules #django中源码的扫描包class StarkConfig(AppConfig): name = 'stark' def ready(self): autodiscover_modules('stark') #注册扫描 # print("adasd")
扫描每个注册的app
4:编写注册函数
4>1:默认样式类
5:注册实例
6: 配置路由
7:路由视图函数做了什么
7>1: 因为路由层调用了urls . 进入urls函数,urls 函数继续调用get_urls函数
7>2:get_urls 函数说明
该函数实现了动态为模型创建增删改查的url的一层分发
一层分发根据表名而定
从注册内容中拿取字典
其中:model 是注册的表名对象
config_obj是 注册的样式对象
temp.append( path("%s/%s/" % (app_label, model_name), config_obj.get_urls) ) 实现当前层的以及分发 效果图:
之后的
config_obj.get_urls 实现二级分发 8:二级分发固定为增删改查 8>1: 解释参数意思
8>2 :django作者把二层分发写在了默认配置类中 这样可以直接在调用配置类的时候,就可以实现二层分发
1 class ModelStark(object): 2 ''' 3 默认配置类 4 ''' 5 list_display = ("__str__",) 6 7 def __init__(self, model): 8 self.model = model 9 10 def list_view(self, request):11 # print(self) # 当前访问模型表对应的配置类对象12 # print(self.model) # 当前访问模型表13 14 data = self.model.objects.all()15 print(data)16 print("-------",self.list_display)17 data_list=[]18 dict1={}19 for obj in data:20 lis =[]21 for msg in self.list_display:22 lis.append(getattr(obj,msg))23 # print("kkkkkkk",lis)24 data_list.append(lis)25 print("jjjjjjjjj",data_list)26 return render(request, 'stark/list_view.html', {27 "data_list":data_list,28 "list_display":self.list_display29 30 31 })32 33 def add_view(self, request):34 return HttpResponse("add_view")35 36 def change_view(self, request, id):37 return HttpResponse("change_view")38 39 def delete_view(self, request, id):40 return HttpResponse("delete_view")41 42 @property43 def get_urls(self):44 temp = [45 path("", self.list_view),46 path("add/", self.add_view),47 path("(\d+)/change/", self.change_view),48 path("(\d+)/delete/", self.delete_view),49 ]50 51 return (temp, None, None)
8>3: 二级分发中的get_ursl 解析
注意:当 '这什么都没写!!!!!!' 的时候,即进入一层分发的界面,这里走的是list_view视图 8:>4 默认配置类的解释
这个model 在注册时候传入.方便数据操作
8>5 :默认配置中的样式 这里的默认配置类只设置的返回"__str__" 即类名 注意!!!! 这里的是('__str__',) 是个元祖!!!
8>5>1 解析4个增删改查 !!!!!!!!!!!!查:
结果:
前端书写
效果:
增,删,改暂时没写
所有代码!! 表目录
staites 表
# -*- coding: utf-8 -*-# @Time : 2019/4/13 11:03# @Author : Endless-cloud# @Site : # @File : stites.py# @Software: PyCharm''' ┏┓ ┏┓+ + ┏┛┻━━━┛┻┓ + + ┃ ┃ ┃ ━ ┃ ++ + + + ████━████ ┃+ ┃ ┃ + ┃ ┻ ┃ ┃ ┃ + + ┗━┓ ┏━┛ ┃ ┃ ┃ ┃ + + + + ┃ ┃ Code is far away from bug with the animal protecting ┃ ┃ + 神兽保佑,代码无bug ┃ ┃ ┃ ┃ + ┃ ┗━━━┓ + + ┃ ┣┓ ┃ ┏┛ ┗┓┓┏━┳┓┏┛ + + + + ┃┫┫ ┃┫┫ ┗┻┛ ┗┻┛+ + + + '''from django.urls import pathfrom django.shortcuts import HttpResponse,renderfrom app01.models import *class ModelStark(object): ''' 默认配置类 ''' list_display = ("__str__",) def __init__(self, model): self.model = model def list_view(self, request): # print(self) # 当前访问模型表对应的配置类对象 # print(self.model) # 当前访问模型表 data = self.model.objects.all() print(data) print("-------",self.list_display) data_list=[] dict1={} for obj in data: lis =[] for msg in self.list_display: lis.append(getattr(obj,msg)) data_list.append(lis) print("jjjjjjjjj",data_list) return render(request, 'stark/list_view.html', { "data_list":data_list, "list_display":self.list_display }) def add_view(self, request): return HttpResponse("add_view") def change_view(self, request, id): return HttpResponse("change_view") def delete_view(self, request, id): return HttpResponse("delete_view") @property def get_urls(self): temp = [ path("", self.list_view), path("add/", self.add_view), path("(\d+)/change/", self.change_view), path("(\d+)/delete/", self.delete_view), ] return (temp, None, None)class StarkSite: ''' stark全局类 ''' def __init__(self): self._registry = {} def register(self, model, admin_class=None, **options): admin_class = admin_class or ModelStark self._registry[model] = admin_class(model) def get_urls(self): # 动态为注册的模型类创建增删改查URL temp = [] # {Book:ModelAdmin(Book),Publish:ModelAdmin(Publish)} for model, config_obj in self._registry.items(): print("---->", model, config_obj) model_name = model._meta.model_name app_label = model._meta.app_label temp.append( path("%s/%s/" % (app_label, model_name), config_obj.get_urls) ) ''' path("stark/app01/book",self.list_view) path("stark/app01/book/add",self.add_view) path("stark/app01/publish",self.list_view) path("stark/app01/publish/add",self.add_view) ''' return temp @property def urls(self): return self.get_urls(), None, Nonesite = StarkSite()
models 表
from django.db import models# Create your models here.class Book(models.Model): title = models.CharField(max_length=32) price = models.DecimalField(max_digits=7, decimal_places=2) pubdate = models.DateField() publish = models.ForeignKey('Publish', on_delete=models.CASCADE, null=True) authors = models.ManyToManyField('Author') state = models.IntegerField(choices=[(1, "已出版"), (2, "未出版社")], default=1) #映射,设置默认值 def __str__(self): return self.titleclass Publish(models.Model): name = models.CharField(max_length=64) city = models.CharField(max_length=64) email = models.EmailField() def __str__(self): return self.nameclass Author(models.Model): name =models.CharField(max_length=32) age =models.IntegerField() au_detail =models.OneToOneField('AuthorDetail',on_delete=models.CASCADE) def __str__(self): return self.nameclass AuthorDetail(models.Model): tel = models.CharField(max_length=32) addr = models.CharField(max_length=64) birthday = models.DateField()
stark表
# -*- coding: utf-8 -*-# @Time : 2019/4/13 11:00# @Author : Endless-cloud# @Site : # @File : stark.py# @Software: PyCharm''' ┏┓ ┏┓+ + ┏┛┻━━━┛┻┓ + + ┃ ┃ ┃ ━ ┃ ++ + + + ████━████ ┃+ ┃ ┃ + ┃ ┻ ┃ ┃ ┃ + + ┗━┓ ┏━┛ ┃ ┃ ┃ ┃ + + + + ┃ ┃ Code is far away from bug with the animal protecting ┃ ┃ + 神兽保佑,代码无bug ┃ ┃ ┃ ┃ + ┃ ┗━━━┓ + + ┃ ┣┓ ┃ ┏┛ ┗┓┓┏━┳┓┏┛ + + + + ┃┫┫ ┃┫┫ ┗┻┛ ┗┻┛+ + + + '''# print("222")from stark.service.stites import site,ModelStarkfrom .models import *class BookConfig(ModelStark): list_display=["title","price"]class PublishConfig(ModelStark): list_display=["name","city"]site.register(Book,BookConfig)site.register(Publish)print(site._registry)
list_view.html
Title 查看数据
{ {obj}} | { % endfor %}
---|
{ {foo}} | { % endfor %}
asd | ads | asd | asd |