day 65 crm(2) admin源码解析,以及简单的仿造admin组件

时间:2021-01-11 19:18:32

 

前情提要:

  crm中的admin组件重写.

    一:admin的autodiscover  

      day 65 crm(2) admin源码解析,以及简单的仿造admin组件

 

          作用:实现扫面该项目中的所有的admin

      day 65 crm(2) admin源码解析,以及简单的仿造admin组件

 

      1:执行顺序->

        按照注册的顺序执行

        

 

 

      二:单例模式

    1:普通案例的格式

day 65 crm(2) admin源码解析,以及简单的仿造admin组件

该案例的内存地址不同,实例对象有自己的实例空间,

  2:单例模式的应用

    单例模式的内存地址相同,在python文件加载过程中.单例模式可以减少相同文件的缓存,

    2>1 基于__new__的单例模式

day 65 crm(2) admin源码解析,以及简单的仿造admin组件

   2>2 基于模块的单例模式  

    python中特有的,模块导入多次只会实现一次

  day 65 crm(2) admin源码解析,以及简单的仿造admin组件

 

     2>2>1基于上例子

    新建一个文件,并创建一个类,

    day 65 crm(2) admin源码解析,以及简单的仿造admin组件

 

 

      

    2>2>2 导入该报重命名

    day 65 crm(2) admin源码解析,以及简单的仿造admin组件

      内存地址相同,即是单例模式,只要是同一个程序就是单例

 

    三:注册功能

    1: admin中应用单例模式

day 65 crm(2) admin源码解析,以及简单的仿造admin组件

 

day 65 crm(2) admin源码解析,以及简单的仿造admin组件

 

 

 day 65 crm(2) admin源码解析,以及简单的仿造admin组件

 

  2:site.register的注册功能

      2>1:在register源码中

      class AdminSite方法__init__内创建了一个空字典,存放单例的内容

     day 65 crm(2) admin源码解析,以及简单的仿造admin组件

          register方法中存放入口参数,model 和admin_class

     day 65 crm(2) admin源码解析,以及简单的仿造admin组件

          其中  

          day 65 crm(2) admin源码解析,以及简单的仿造admin组件

          如果 admin_class =None

            1 or 0  1

            2 or 3  2

            0 or 1  1

           如果有值,则走admin_calss 即自定制, 如果没有值则,ModelAdmin

      modelAdmin 为默认配置类

      day 65 crm(2) admin源码解析,以及简单的仿造admin组件 

        当注册时在字典中增加key,valuse

      day 65 crm(2) admin源码解析,以及简单的仿造admin组件

      2>2 如果全部注册完了以后,可以尝试打印该字典

      如只注册了3个

    day 65 crm(2) admin源码解析,以及简单的仿造admin组件

      则会显示5个,因为系统自动注册了两个,auto 和group

  启动下看看:::

 day 65 crm(2) admin源码解析,以及简单的仿造admin组件

    2 >3 register方法

      该方法 会循环的从字典中拿取key和values ,

        key为model 即为表明  

        valuse为样式类,如果不填写则传入默认的

 

      

     四:设置url APPEND_SLASH参数

      day 65 crm(2) admin源码解析,以及简单的仿造admin组件

        day 65 crm(2) admin源码解析,以及简单的仿造admin组件

        默认效果

    day 65 crm(2) admin源码解析,以及简单的仿造admin组件

 

       五:url的分发

      1 :url中的分发

    django自带的以调用属性的方式,显示,使用为使用了@properp ,使方法以属性的形式可以代用

   day 65 crm(2) admin源码解析,以及简单的仿造admin组件

        

      2:样式:    

    path('路由/',([

        path('text01/',text01),

        path('text02/',text02),

      ],None,None))

day 65 crm(2) admin源码解析,以及简单的仿造admin组件

 

      3:运行顺序

      day 65 crm(2) admin源码解析,以及简单的仿造admin组件

 

     4:效果:

      day 65 crm(2) admin源码解析,以及简单的仿造admin组件

          day 65 crm(2) admin源码解析,以及简单的仿造admin组件

 

     5:url 路由的多级分发

        就是把原视图方法的地方在进行一次路由分发

      day 65 crm(2) admin源码解析,以及简单的仿造admin组件

 

     5>1 :  运行路线

      day 65 crm(2) admin源码解析,以及简单的仿造admin组件

        5>2 :效果图

      day 65 crm(2) admin源码解析,以及简单的仿造admin组件

          day 65 crm(2) admin源码解析,以及简单的仿造admin组件

 

   六:从新设计admin的url分发

    1:设置url的分发

      在原视图函数的位置上设置一个可执行函数,返回值为视图函数,或者视图函数分层

    day 65 crm(2) admin源码解析,以及简单的仿造admin组件

 

       2:动态的为模型类创建增删改查url

      2>1 通过刚才字典的进行进一步操作

      

    3: 拿到注册的字典,进行操作

    循环的从字典内拿出来 key 和values

    day 65 crm(2) admin源码解析,以及简单的仿造admin组件

 

 

          注意:valuse 的值是分为 配置类,和默认配置类

    4:给temp增加path路径

    day 65 crm(2) admin源码解析,以及简单的仿造admin组件

 

         4>1:参照admin表的模式. 

      自定义明/app名字/表明/操作名

      day 65 crm(2) admin源码解析,以及简单的仿造admin组件

       4>2: 通过model的模型类获取app名字和model(表名)

    4:2>1 获取表名

    day 65 crm(2) admin源码解析,以及简单的仿造admin组件

       4:2>2 获取app名

           day 65 crm(2) admin源码解析,以及简单的仿造admin组件

 

 

 

      5: 最终一级效果图

day 65 crm(2) admin源码解析,以及简单的仿造admin组件    

 

       :效果图:

     day 65 crm(2) admin源码解析,以及简单的仿造admin组件

    day 65 crm(2) admin源码解析,以及简单的仿造admin组件

 

 

     六:二层分发:(固定增删改查)

    1: 在一层分发后面再开一个分发函数,get_urls2()

  day 65 crm(2) admin源码解析,以及简单的仿造admin组件

        2:函数内部,

      增删改查,4个path

           注意什么都不写,即默认为点开一层的效果,我们这里让他为查询界面

      day 65 crm(2) admin源码解析,以及简单的仿造admin组件

 

       day 65 crm(2) admin源码解析,以及简单的仿造admin组件

 

 

     七:自己设计一个stark组件(自己写一个admin)

    1:创建一个新的app  :stark

    day 65 crm(2) admin源码解析,以及简单的仿造admin组件

      2:把app注册到setting中

day 65 crm(2) admin源码解析,以及简单的仿造admin组件

  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")

 

day 65 crm(2) admin源码解析,以及简单的仿造admin组件

 

  扫描每个注册的app

day 65 crm(2) admin源码解析,以及简单的仿造admin组件

 

 

day 65 crm(2) admin源码解析,以及简单的仿造admin组件

 

  4:编写注册函数

day 65 crm(2) admin源码解析,以及简单的仿造admin组件

 

day 65 crm(2) admin源码解析,以及简单的仿造admin组件

  4>1:默认样式类

day 65 crm(2) admin源码解析,以及简单的仿造admin组件

 5:注册实例

day 65 crm(2) admin源码解析,以及简单的仿造admin组件

 

 6: 配置路由

day 65 crm(2) admin源码解析,以及简单的仿造admin组件

 

 day 65 crm(2) admin源码解析,以及简单的仿造admin组件

 

 

 7:路由视图函数做了什么

    7>1: 因为路由层调用了urls . 进入urls函数,urls 函数继续调用get_urls函数

 

  day 65 crm(2) admin源码解析,以及简单的仿造admin组件

      7>2:get_urls 函数说明

    该函数实现了动态为模型创建增删改查的url的一层分发

    一层分发根据表名而定

day 65 crm(2) admin源码解析,以及简单的仿造admin组件

    从注册内容中拿取字典

day 65 crm(2) admin源码解析,以及简单的仿造admin组件

其中:model 是注册的表名对象

  config_obj是 注册的样式对象

  

temp.append(
path("%s/%s/" % (app_label, model_name), config_obj.get_urls)
)
    实现当前层的以及分发
  效果图:
day 65 crm(2) admin源码解析,以及简单的仿造admin组件

day 65 crm(2) admin源码解析,以及简单的仿造admin组件

 

 之后的
config_obj.get_urls 实现二级分发
    8:二级分发固定为增删改查
      8>1: 解释参数意思
    day 65 crm(2) admin源码解析,以及简单的仿造admin组件

 

      8>2 :django作者把二层分发写在了默认配置类中
        这样可以直接在调用配置类的时候,就可以实现二层分发
day 65 crm(2) admin源码解析,以及简单的仿造admin组件day 65 crm(2) admin源码解析,以及简单的仿造admin组件
 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)
View Code
 

          8>3: 二级分发中的get_ursl 解析

  day 65 crm(2) admin源码解析,以及简单的仿造admin组件

 

 注意:当 '这什么都没写!!!!!!' 的时候,即进入一层分发的界面,这里走的是list_view视图

    8:>4 默认配置类的解释
day 65 crm(2) admin源码解析,以及简单的仿造admin组件

 

这个model 在注册时候传入.方便数据操作
day 65 crm(2) admin源码解析,以及简单的仿造admin组件

 

8>5 :默认配置中的样式
这里的默认配置类只设置的返回"__str__" 即类名
注意!!!!
这里的是('__str__',) 是个元祖!!!

day 65 crm(2) admin源码解析,以及简单的仿造admin组件

 

8>5>1
解析4个增删改查
!!!!!!!!!!!!查:
    day 65 crm(2) admin源码解析,以及简单的仿造admin组件

 

    结果:
day 65 crm(2) admin源码解析,以及简单的仿造admin组件

 

    前端书写
day 65 crm(2) admin源码解析,以及简单的仿造admin组件

  

效果:
day 65 crm(2) admin源码解析,以及简单的仿造admin组件

 

 

 增,删,改暂时没写

day 65 crm(2) admin源码解析,以及简单的仿造admin组件

 

 所有代码!!
表目录
day 65 crm(2) admin源码解析,以及简单的仿造admin组件

 

 
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>