前情提要:

  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组件的更多相关文章

  1. django之admin源码解析

    解析admin的源码 第一步:项目启动,加载settings文件中的 INSTALLED_APPS 里边有几个app就加载几个,按照注册顺序来执行. 第二步:其中加载的是admin.py,加载每一个a ...

  2. admin源码解析以及仿照admin设计stark组件

    ---恢复内容开始--- admin源码解析 一 启动:每个APP下的apps.py文件中. 首先执行每个APP下的admin.py 文件. def autodiscover(): autodisco ...

  3. django -admin 源码解析

    admin源码解析 单例模式 单例模式(Singleton Pattern)是一种常用的软件设计模式,该模式的主要目的是确保某一个类只有一个实例存在.当你希望在整个系统中,某个类只能出现一个实例时,单 ...

  4. admin源码解析及自定义stark组件

    admin源码解析 单例模式 单例模式(Singleton Pattern)是一种常用的软件设计模式,该模式的主要目的是确保某一个类只有一个实例存在.当你希望在整个系统中,某个类只能出现一个实例时,单 ...

  5. abp vnext2.0之核心组件模块加载系统源码解析与简单应用

    abp vnext是abp官方在abp的基础之上构建的微服务架构,说实话,看完核心组件源码的时候,很兴奋,整个框架将组件化的细想运用的很好,真的超级解耦.老版整个框架依赖Castle的问题,vnext ...

  6. Spring源码解析-AOP简单分析

    AOP称为面向切面编程,在程序开发中主要用来解决一些系统层面上的问题,比如日志,事务,权限等等,不需要去修改业务相关的代码. 对于这部分内容,同样采用一个简单的例子和源码来说明. 接口 public ...

  7. 【Spring源码解析】—— 简单工厂模式的BeanFactory的超简版实现

    一.什么是简单工厂模式 设计模式的核心是“分工”,通过分工将对象与职责划分的更细化,进而提升系统设计的可扩展性,使其更容易维护. 开闭原则:对扩展开放,对修改关闭:要增加一个新的处理逻辑,可以开一个新 ...

  8. HashMap源码解析(简单易懂)

    /* 每一个key-value存储在Node<K,V>中,HashMap由Node<K,V>[]数 组组成. */ static class Node<K,V> i ...

  9. 6 admin(注册设计)源码解析、单例模式

    1.单例模式 https://www.cnblogs.com/yuanchenqi/articles/8323452.html 单例模式(Singleton Pattern)是一种常用的软件设计模式, ...

随机推荐

  1. aspx导出文件

    System.IO.StringWriter sw = new System.IO.StringWriter(); HtmlTextWriter htw = new HtmlTextWriter(sw ...

  2. Mybatis传值为空需要配置JdbcType来解决吗?(XML文件不需要配置JdbcType)

    1,解决思路,配置自定义的语言驱动,重写自己的Paramethander package cn.com.servyou.gxdqy.tool.xmlhelper; import org.apache. ...

  3. Notepad++ 中如何将代码格式化

    Notepad++ 中如何将代码格式化   在阅读别人的代码时偶尔会遇到格式很乱,阅读起来很费劲的情况,若手动改,很容易出错且很费时间,这时可以借助一些专业的编辑器来格式化代码,NotePad++是一 ...

  4. Jsp+servlet+mysql搭建套路

    1.建立数据库根据需求建立相应的数据库确立数据库的字段.属性.主键等2.建立javaweb项目,搭建开发环境在开发环境的/WebRoot/WEB-INF下建立lib文件夹,存放需要使用的jar包常用的 ...

  5. UVa 11280 Flying to Fredericton (DP + Dijkstra)

    题意:给出n(2<=n<=100)个城市之间的m(0<=m<=1000)条航线以及对应的机票价格,要求回答一些询问,每个询问是给出最大停留次数S,求从其实城市Calgary到终 ...

  6. The serializable class XXX does not declare a static final serialVersionUID field of type long

    问题: 在Eclipse中,继承类时,总是提示下面的警告(Warning),按理说警告是没有关系的,但是程序看起来老不爽了,这是强迫症的关系(呵呵) The serializable class XX ...

  7. i9-9900k烤机

    新装机一台,记录烤机参数 硬件配置: cpu: i9-9900k 主板:技嘉Z390 AORUS PRO WIFI 内存:海盗船ddr4 3200 显卡:技嘉gtx1080ti 硬盘:三星970Pro ...

  8. 如何更新world文档的目录

    在想要设置目录的文档页,右键 -> 更新域, 或者在想要设置目录的文档页,按下 F9 即可 拓展: 在目录文档页  ,按Ctrl 并且单击鼠标可以跟踪目标连接 如果内容对您有所帮助,请打赏--- ...

  9. How Many Tables HDOJ

    How Many Tables Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)T ...

  10. javascript data format

    Date.prototype.Format = function(fmt) { var o = { "M+" : this.getMonth()+1, //月份 "d+& ...