• 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作者把二层分发写在了默认配置类中
            这样可以直接在调用配置类的时候,就可以实现二层分发
     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 解析

      

     注意:当 '这什么都没写!!!!!!'  的时候,即进入一层分发的界面,这里走的是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>
    
    
    
     

     

         

         

  • 相关阅读:
    Jedis、RedisTemplate、StringRedisTemplate之间的比较
    阿里云服务器搭建DiscuzQ
    阿里云Docker加速镜像配置
    IDEA不卡配置
    Tomcat中出现"RFC 7230 and RFC 3986"错误的解决方法
    Eclipse设置保存时自动格式化代码
    VUE中v-for和v-if不能同时使用的问题
    JS中设置cookie,读取cookie,删除cookie
    JS中数组的拷贝方法
    在VSCode中开启ESLint风格审查
  • 原文地址:https://www.cnblogs.com/baili-luoyun/p/10699046.html
Copyright © 2020-2023  润新知