simpleui layer 自动更新数据并且在migrate时layer不自动加载

前言

这个问题应该不会有很多同学遇到,但是如果遇到了可以参考解决。

当你使用simpleui layer 时肯定会遇到更新了数据库数据后,layer中的数据并没有自动更新的情况。而当你更新解决完数据自动更新之后,很有可能会引出另一个问题,当模型结构发生变更时,恰好自动更新layer的时候需要依赖这个模型,嘿嘿,那你就会在migrate的时候报错,类似:

django.db.utils.OperationalError: (1054, "Unknown column 'assets_DomainList.cloud_certificate_id' in 'field list'")

一 自动更新layer数据

通过admin_action装饰器将layer所需要的属性都进行赋值。

1 生成layer

1.1 按钮

 @admin_action(short_description='导入域名列表', _type='success', icon='el-icon-s-promotion',
                  layer=ImportDomainListLayer()())
    def import_domain_list(self, request, queryset):
        return JsonResponse(data={
            'status': 'success',
            'msg': '处理成功!'
        })

1.2 layer装饰器

def admin_action(short_description=None, icon=None, _type=None, confirm=None, style=None, layer=None):
    """
    后台action属性装饰器
    :param layer:
    :param style:
    :param short_description:
    :param icon:
    :param _type:
    :param confirm:
    :return:
    """
    def decorator(func):
        func.short_description = short_description
        func.icon = icon
        func.type = _type
        func.confirm = confirm
        func.style = style
        func.layer = layer

        @wraps(func)
        def wrapper(*args, **kwargs):
            return func(*args, **kwargs)

        return wrapper

    return decorator

1.3 合成layer的类

class ImportDomainListLayer:
    def __init__(self):
        self.layer = {
            'title': '导入域名和记录',
            'tips': '清空之后重新导入,不同凭证对应不同的平台。',
            'confirm_button': '确认提交',
            'cancel_button': '取消',
            'width': '40%',
            'labelWidth': "80px",
            'params': []
        }
        self.dst_cloud_select = {
            'type': 'select',
            'key': 'dst_cloud',
            'label': '目标云平台凭证',
            'size': 'small',
            'options': []
        }

    def generate_layer(self):
        self.dst_cloud_select['options'] = [{'key': cc.id, 'label': cc.name} for cc in CloudCertificate.objects.all()]
        self.layer['params'] = [
            self.dst_cloud_select,
        ]
        return self.layer

    @admin_layer_load
    def __call__(self, *args, **kwargs):
        return self.generate_layer()

2 自动更新layer数据

通过信号在依赖的模型每次新增数据后自动刷新layer属性数据。

2.1 信号函数

@receiver(post_delete, sender=CloudCertificate, dispatch_uid='post_delete_CloudCertificate')
def del_import_domain_list_layer(sender, **kwargs):
    logger.info("CloudCertificate del 触发信号。")
    DomainListMixins.import_domain_list.layer = ImportDomainListLayer()()

 

二 在migrate时layer不自动加载

思路就是在migrate的时候忽略掉layer的加载。

1 控制不加载的装饰器

def admin_layer_load(func):
    """
    在migrate模式下,不加载layer
    :param func:
    :return:
    """
    @wraps(func)
    def wrapper(*args, **kwargs):
        return 'pass' if 'migrate' in sys.argv else func(*args, **kwargs)
    return wrapper

2 在调用layer的时候加入判断

    @admin_layer_load
    def __call__(self, *args, **kwargs):
        return self.generate_layer()

 

要是大佬们有更好的解决办法,可以留言赐教。

posted @ 2024-01-29 12:35  腐汝  阅读(45)  评论(0编辑  收藏  举报