前情提要:
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 AppConfig from 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_display 29 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 @property 43 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 path from django.shortcuts import HttpResponse,render from 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, None site = 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.title class Publish(models.Model): name = models.CharField(max_length=64) city = models.CharField(max_length=64) email = models.EmailField() def __str__(self): return self.name class 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.name class 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,ModelStark from .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
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <!-- 最新版本的 Bootstrap 核心 CSS 文件 --> <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@3.3.7/dist/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous"> </head> <body> <h3>查看数据</h3> <table> <tbody> <tr> {% for obj in list_display %} <th> {{obj}} </th> {% endfor %} </tr> {% for msg in data_list %} <tr> {% for foo in msg %} <td> {{foo}} </td> {% endfor %} </tr> {% endfor %} </tbody> </table> <table border="1"> <tr> <td>asd</td> <td>ads</td> <td>asd</td> <td>asd</td> </tr> </table> </body> </html>