zoukankan      html  css  js  c++  java
  • CRM项目之stark组件

    1. stark也是一个app(用startapp stark创建),目标时把这个做成一个可以拔插的组件
    2. setting文件下INSTALLED_APPS  路径要配置好(app的注册)
    3. 写好sites.py中的site类,实例化出一个类对象,其他文件都直接引用这个类对象(单例模式),
    4. 模型类和数据库也要确定好

    本节内容:

    1、写stark的前期准备工作
    2、stark组件之启动
    3、stark组件之注册功能
    4、stark组件之类变量查询
    5、stark组件之url二级分发
    6、静态文件和模板的引入问题
    7、stark组件展示表格的体数据(即展示记录)
    8、stark组件之展示表头数据
    9、stark组件之默认列(为所有的查看页面默认显示编辑、删除、选择按钮)
    

    一、写stark的前期准备工作

    1. stark也是一个app(用startapp stark创建),目标时把这个做成一个可以拔插的组件
    2. setting文件下INSTALLED_APPS  路径要配置好(app的注册)
    3. 写好sites.py中的site类,实例化出一个类对象,其他文件都直接引用这个类对象(单例模式),
    4.模型类和数据库也要确定好

    二. 前期准备工作

       

    1.1 在stark文件的app.py里面加入配置       

      

    from django.apps import AppConfig
        
    from django.utils.module_loading import autodiscover_modules
    class StarkConfig(AppConfig):
        name = 'stark'
        def ready(self):
            autodiscover_modules('stark')
    
    
    # 必须要配置这个方法,在启动django项目的时候才能自动的去每个app下,去自动加载stark.py文件
    View Code

     #  在每一个app文件夹下都要创建一个stark.py文件,这样在配置好url后,启动django项目,才会自动去每一个app下加载该文件

    三、stark组件之注册

      这里主要做了两件事情

      1. stark源码中我们写好starksite类,并实例化一个对象
      2.在相应的APP下,注册site

    # 在stark文件加的stark.py文件中定义注册方法

    from django.shortcuts import HttpResponse,render
    from django.urls import path,re_path
    #主要有两个类,一个是基本类Starksite,一个是配置类Modelsite
    class Modelstark():  #配置类
        list_display = ['__str__']
        def __init__(self,model):
        self.model = model
     
    class Starksite():
        ...
        #Starksite  基本类
        #model   注册类模型
        #ModelStark  注册模型类的配置类
        '''
        def __init__(self):
            self._registry = {}
     
        #注册的方法
        def registry(self,model, starkclass=None):  
            #传参,注册的模型类和对应的配置类,这里传的都是类名,实际就是调用函数,所以要用到self
    starkclass = starkclass or Modelstark  
    # 若自定制有子类配置类对象则用传入的子类的,没有用默认父类的
    self._registry[model] = stark_class[model]  
    该模型类为键,该模型了的配置类为值
    site = Starksite()  #实例化对象        
    View Code

    # 在app01下的stark.py文件里面实现注册

    from stark.service.sites import site,Modelstark
    from .model import *
    #可以定制化配置类
    class BookConfig(ModelStark):  
    #这里继承ModelStark,是如果自定制类中有list_display,就返回自定制的lsit_display,没有就返回默认的父类的list_display
        def show_authors:
            return '|',join([obj.name for obj in obj.authors])
        lsit_display = ['title', 'price', show_authors]  #这里的不加括号是用反射,展示数据
        site.register(Book,BookConfig)
        site.register(Publish)
        site.register(Author)    
        print(site._registry)  #指定值的键值对,注册多少就有多少,django自带的要多两个,内部自带的
    View Code

    四、stark组件之类变量查询

    回顾我们的面向对象的知识:
    类变量的查询的先后顺序(有继承关系的):
    1、首先在自己对象的内存空间中找该变量,找不到的话
    2、就到自己的类空间中找,还找不到的话
    3、就到自己的父类空间中找,一直逐级往上找,再找不到的话,就报错
    

    五、stark组件之url二级分发

    这里我们模仿,admin组件的使用静态方法进行url二级分发
    1、首先在urls中配置path路径,(这一步属于用户操作)
    2、在基本类中配置好一级分发
    3、在配置类中配置好二级分发
    
    # stark.py文件下的代码
    class ModelStark():  # 配置类
        def __init__(self,model):
              self.model=model
              self.app_labe=app_label
              self.model_name=model_name
        # urls二级分发
        @property
        def get_urls(self):
            temp = [
                path("", self.list_view, name="%s_%s_list"%(self.app_label,self.model_name)),
                path("add/", self.add_view, name="%s_%s_add"%(self.app_label,self.model_name)),
                re_path("(d+)/change/", self.change_view, name="%s_%s_change"%(self.app_label,self.model_name)),
                re_path("(d+)/delete/", self.delete_view, name="%s_%s_delete"%(self.app_label,self.model_name)),
            ]
            return temp, None, None
    
    
    class StarkSite():
        '''
        # StarkSite: 基本类
        # model: 注册模型类
        # ModelStark: 注册模型类的配置类
        '''
        def __init__(self):
            self._registry = {}  #定义这个字典在url二级分发时体现出阿来    
         #注册方法
        def register(self, model, admin_class=None):
            admin_class = admin_class or ModelStark
            self._registry[model] = admin_class(model)
    
        def get_urls(self):  #  动态为注册的模型类创建增删改查URL
            temp = []
            for model, config_obj in self._registry.items():  
        #{Book:Bookconfig(Book),Publish:ModelStark(Publish)}  #类模型和配置类对象
                model_name = model._meta.model_name  # 拿到该表的小写表名
                app_label = model._meta.app_label  # 拿到该表所在的APP名称
                temp.append(
                    path('%s/%s/' % (app_label, model_name),config_obj.urls) # 对象直接点该属性,这是一个方法封装的属性
                )
           '''
           最终效果:
           # 1 path('app01/book/',Bookconfig(Book).urls),
    
            path('app01/book/',Bookconfig(Book).list_view),
            path('app01/book/add',Bookconfig(Book).add_view),
            path('app01/book/(d+)/change/',Bookconfig(Book).change_view),
            path('app01/book/(d+)/delete/',Bookconfig(Book).delete_view),
            '''
            return temp
    
        @property # 将一个方法变成属性,这样在使用的时候就可以不用加括号,直接点
        def urls(self):
            return self.get_urls(), None, None
    
    site = StarkSite()
    
    # 用户项目中的urls.py文件中配置path路径
    
    from stark.service.sites import site
    
    urlpatterns = [
        path('admin/', admin.site.urls),
        path('stark/',site.urls),
    ]
    View Code
    
    
    

    六、静态文件和模板的引入问题

    主要这里我们要将stark组件做成可插拔式的,所有静态文件和模板文件都要放在我们的stark文件夹下。
    这样就可以保证用户在使用我们的stark组件时,不会缺少配置文件。
    

    七、stark组件展示表格的体数据(即展示记录)

    这个统一在最后面的实例中有详解
    

    八、stark组件之展示表头数据

    这个统一在最后面的实例中有详解
    

    九、stark组件之默认列

    用户app01下的models.py文件

    # Create your models here.
    from django.db import models
    
    # Create your models here.
    
    class Author(models.Model):
        nid = models.AutoField(primary_key=True)
        name=models.CharField( max_length=32, verbose_name='姓名')
        age=models.IntegerField()
        def __str__(self):
            return self.name
    
    class Publish(models.Model):
        nid = models.AutoField(primary_key=True)
        name=models.CharField( max_length=32, verbose_name='名称')
        city=models.CharField( max_length=32)
        email=models.EmailField()
    
        def __str__(self):
            return self.name
    
    class Book(models.Model):
    
        nid = models.AutoField(primary_key=True)
        title = models.CharField( max_length=32, verbose_name='书名')
        # pub_date=models.DateField()
        price=models.DecimalField(max_digits=5,decimal_places=2)
        state=models.IntegerField(choices=[(1,"已出版"),(2,"未出版社")],default=1)
        # 与Publish建立一对多的关系,外键字段建立在多的一方
        publish=models.ForeignKey(to="Publish",to_field="nid",on_delete=models.CASCADE)
        # 与Author表建立多对多的关系,ManyToManyField可以建在两个模型中的任意一个,自动创建第三张表
        authors=models.ManyToManyField(to='Author',)
        def __str__(self):
            return self.title
    
    class AuthorDetail(models.Model):
        birthday = models.DateField()
        telephone = models.BigIntegerField()
        addr = models.CharField(max_length=64)
        # author=models.OneToOneField("Author",on_delete=models.CASCADE)
        def __str__(self):
            return str(self.telephone)
    View Code

    #  记得使用makemigration和migrate导入到数据库中

    用户app01下的stark.py

    class BookConfig(ModelStark):
    
        def show_authors(self, obj=None, is_header=False):
            if is_header:
                return 'author'
            return '|'.join([obj.name for obj in obj.authors.all()])
    
        list_display=["title","price",show_authors]
        
    
    
    
    class PublishConfig(ModelStark):
    
        list_display = ['name', 'city', 'email']
        list_display_links = ['name','city']
        model_form_class = PublishModelForm
    
    site.register(Book,BookConfig)
    site.register(Publish,PublishConfig)
    site.register(Author)
    site.register(AuthorDetail)
    print(site._registry)
    View Code

    stark文件下的sites.py文件

    class StarkSite:
        '''
        stark全局类
        '''
        def __init__(self):
            self._registry = {}  #定义这个字典在url二级分发时体现出阿来
    
        #注册方法
        def register(self, model, admin_class=None):
            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()
    View Code
     
  • 相关阅读:
    Git命令与使用
    Android与WebView的JS交互
    Android 中关于硬件加速的使用和问题
    Activity-生命周期和启动模式
    Activity-恢复与保存状态或数据
    Android中Paint的一些使用心得记录
    Java中sleep,wait的区别
    C#基本类型
    LeetCode74 搜索二维矩阵
    leetcode 43 字符串相乘 java
  • 原文地址:https://www.cnblogs.com/yang950718/p/10707372.html
Copyright © 2011-2022 走看看