day 65 crm(2) admin源码解析,以及简单的仿造admin组件
前情提要:
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作者把二层分发写在了默认配置类中
这样可以直接在调用配置类的时候,就可以实现二层分发
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))
# print("kkkkkkk",lis)
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)
8>3: 二级分发中的get_ursl 解析

注意:当 '这什么都没写!!!!!!' 的时候,即进入一层分发的界面,这里走的是list_view视图 8:>4 默认配置类的解释
这个model 在注册时候传入.方便数据操作
8>5 :默认配置中的样式
这里的默认配置类只设置的返回"__str__" 即类名
注意!!!!
这里的是('__str__',) 是个元祖!!!
8>5>1
解析4个增删改查
!!!!!!!!!!!!查:
结果:
前端书写
效果:
增,删,改暂时没写

所有代码!!
表目录
staites 表
# -*- coding: utf- -*-
# @Time : // :
# @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=)
price = models.DecimalField(max_digits=, decimal_places=)
pubdate = models.DateField()
publish = models.ForeignKey('Publish', on_delete=models.CASCADE, null=True)
authors = models.ManyToManyField('Author')
state = models.IntegerField(choices=[(, "已出版"), (, "未出版社")], default=) #映射,设置默认值
def __str__(self):
return self.title class Publish(models.Model):
name = models.CharField(max_length=)
city = models.CharField(max_length=)
email = models.EmailField() def __str__(self):
return self.name
class Author(models.Model):
name =models.CharField(max_length=)
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=)
addr = models.CharField(max_length=)
birthday = models.DateField()
stark表
# -*- coding: utf- -*-
# @Time : // :
# @Author : Endless-cloud
# @Site :
# @File : stark.py
# @Software: PyCharm
'''
┏┓ ┏┓+ +
┏┛┻━━━┛┻┓ + +
┃ ┃
┃ ━ ┃ ++ + + +
████━████ ┃+
┃ ┃ +
┃ ┻ ┃
┃ ┃ + +
┗━┓ ┏━┛
┃ ┃
┃ ┃ + + + +
┃ ┃ Code is far away from bug with the animal protecting
┃ ┃ + 神兽保佑,代码无bug
┃ ┃
┃ ┃ +
┃ ┗━━━┓ + +
┃ ┣┓
┃ ┏┛
┗┓┓┏━┳┓┏┛ + + + +
┃┫┫ ┃┫┫
┗┻┛ ┗┻┛+ + + +
''' # print("")
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="">
<tr>
<td>asd</td>
<td>ads</td>
<td>asd</td>
<td>asd</td>
</tr>
</table>
</body>
</html>
day 65 crm(2) admin源码解析,以及简单的仿造admin组件的更多相关文章
- django之admin源码解析
解析admin的源码 第一步:项目启动,加载settings文件中的 INSTALLED_APPS 里边有几个app就加载几个,按照注册顺序来执行. 第二步:其中加载的是admin.py,加载每一个a ...
- admin源码解析以及仿照admin设计stark组件
---恢复内容开始--- admin源码解析 一 启动:每个APP下的apps.py文件中. 首先执行每个APP下的admin.py 文件. def autodiscover(): autodisco ...
- django -admin 源码解析
admin源码解析 单例模式 单例模式(Singleton Pattern)是一种常用的软件设计模式,该模式的主要目的是确保某一个类只有一个实例存在.当你希望在整个系统中,某个类只能出现一个实例时,单 ...
- admin源码解析及自定义stark组件
admin源码解析 单例模式 单例模式(Singleton Pattern)是一种常用的软件设计模式,该模式的主要目的是确保某一个类只有一个实例存在.当你希望在整个系统中,某个类只能出现一个实例时,单 ...
- abp vnext2.0之核心组件模块加载系统源码解析与简单应用
abp vnext是abp官方在abp的基础之上构建的微服务架构,说实话,看完核心组件源码的时候,很兴奋,整个框架将组件化的细想运用的很好,真的超级解耦.老版整个框架依赖Castle的问题,vnext ...
- Spring源码解析-AOP简单分析
AOP称为面向切面编程,在程序开发中主要用来解决一些系统层面上的问题,比如日志,事务,权限等等,不需要去修改业务相关的代码. 对于这部分内容,同样采用一个简单的例子和源码来说明. 接口 public ...
- 【Spring源码解析】—— 简单工厂模式的BeanFactory的超简版实现
一.什么是简单工厂模式 设计模式的核心是“分工”,通过分工将对象与职责划分的更细化,进而提升系统设计的可扩展性,使其更容易维护. 开闭原则:对扩展开放,对修改关闭:要增加一个新的处理逻辑,可以开一个新 ...
- HashMap源码解析(简单易懂)
/* 每一个key-value存储在Node<K,V>中,HashMap由Node<K,V>[]数 组组成. */ static class Node<K,V> i ...
- 6 admin(注册设计)源码解析、单例模式
1.单例模式 https://www.cnblogs.com/yuanchenqi/articles/8323452.html 单例模式(Singleton Pattern)是一种常用的软件设计模式, ...
随机推荐
- Python 的stat 模块
#!/usr/bin/env python#-*- encoding:UTF-8 -*- import os,time,stat fileStats = os.stat ( 'test.txt' ) ...
- [开源,学习,分享]UWP第三方简书客户端分享
简介 Windows10正式版发布到现在,我利用零零碎碎的一些时间对UWP进行一些学习,也基于这门技术开发了一个第三方的简书App. 基本界面 优酷视频: http://v.youku.com/v_s ...
- 协议 protocol
协议声明类需要实现的的方法,为不同的类提供公用方法,一个类可以有多个协议,但只能有一个父类,即单继承.它类似java中的接口. 正式协议(formal protocol)--------------- ...
- sql语句增删改查(方便你我Ta)
又自学,把SQL的一些常用语句复习了一遍. 整理如下: 1增 1.1[插入单行]insert [into] <表名> (列名) values (列值)例:insert into Strde ...
- struts2和JSON的数据交互
一.实验环境 1.struts2基本包 2.json-plugin 在struts2的lib下可以找到. 3.web.xml 加入struts2 <filter> <filter-n ...
- 20155319 2016-2017-2 《Java程序设计》第九周学习总结
20155319 2016-2017-2 <Java程序设计>第九周学习总结 教材学习内容总结 整合数据库 ==16.1.1 JDBC简介== JDBC全名Java DataBase Co ...
- no_namespace rename 在C++中是什么意思啊
#import "C:\Program Files\Common Files\System\ado\msado15.dll" no_namespace rename("E ...
- hdu 1300 Deck
题目 分析:对于n张卡片的最佳摆法,我们只需要在n-1张卡片的摆法下面加一张边缘与桌檐重合的卡片,并将所有卡片一起向桌檐外移动.对于一种最佳摆法,其中心一定在桌檐上,所以一定符合杠杆原理,支点是桌檐. ...
- hdu 4004 最大值最小化
http://acm.hdu.edu.cn/showproblem.php?pid=4004 一条线段长度为L,线段上有n个点,最多选取 m-1 个点,使得包括线段端点在内的相邻点之间的最大距离值最小 ...
- SSH框架中配置log4j的方法
SSH框架中使用log4j的方便之处 1. 动态的改变记录级别和策略,即修改log4j.properties,不需要重启Web应用,这需要在web.xml中设置一下.2. 把log文件定在 /WEB- ...









