在django中使用django-simpleui框架,自定义表单的checkbox部件,使用el-switch替代的一种实现方法

0
(0)

django-simpleui是一套优秀的django admin增强组件, 适合于熟悉 vue2/element-ui技术栈的朋友,可以很方便的使用element-ui中的前端组件美化页面。其pypi站的链接 https://pypi.org/project/simpleui/。有社区版和专业版,社区版使用了element-ui的默认样式,其专业版功能强大,而且样式更加美观。

自定义组件仍然遵循django的规范,本文省略了创建项目和应用等一系列过程,只写核心过程

第一步,在admin.py中设置 form属性

class XXXAdmin(admin.ModelAdmin):
    ...
    form = XXXForm

第二步,在form.py中定义 XXXForm,在widgets属性中,设置字段(field)和控件(widget)的对应关系

class XXXForm(forms.ModelForm):
    class Meta:
        model = UibReport
        fields = forms.ALL_FIELDS
        widgets = {
        	'yourfield': ElSwitchWidget(),
        }

第三步,定义ElSwitchWidget

class ElSwitchWidget(widgets.Widget):
    """ 默认显示的标签,如需改变,则传入不同的labels """
    labels = {1: '启用', 0: '停用'}

    def __init__(self, attrs=None):
        if attrs is not None:
            attrs = attrs.copy()
            self.labels = attrs.pop('labels', self.labels)
        super().__init__(attrs)
    
    # 将js脚本和页面模板分开处理,以保持文件结构清晰,如果代码比较简单,也可以不拆分 js文件,直接在 模板的 <script>段直接实现
    @property
    def media(self):
        js = ["js/widget/el-switch.js"]
        return forms.Media(js=["%s" % path for path in js])
    # 实现render方法,引用了widget目录下的el-switch.html模板文件
    def render(self, name, value, attrs=None, renderer=None):
        out = render_to_string(template_name='widget/el-switch.html',
                               context={'name': name, 'value': value, 'attrs': attrs, 'labels': self.labels})
        return out

第四步,在部件目录widget中创建 el-switch.html,模板中使用了 el-switch组件

<div id="id_{{name}}">
    <input type="hidden" name="{{ name }}" :value="value" />
    <el-switch
      v-model="value"
      active-value="1"
      inactive-value="0"
      active-color="#13ce66"
      inactive-color="#bbb">
    </el-switch>
    <span v-if="value == '1'" v-html="labels[1]"></span>
    <span v-else v-html="labels[0]"></span>
</div>
<script type="text/javascript">
    initElSwitchWidget('{{ name }}', '{{value}}', {{ labels|safe }})
</script>

第五步,在静态资源目录js/widget中创建 el-switch.js文件,定义了initElSwitchWidget方法, 该文件在部件类的media属性中引用

function initElSwitchWidget(name, value, labels) {
    new Vue({
        el: '#id_'+name,
        data: {
            value: value,
            labels: labels,
        }
    })
}

以上拆分出许多文件 admin.py form.py widget.py el-switch.html el-switch.js, 是我在项目中使用的规范, 每一类文件的路径和命名都遵守相同的规则,更好的管理大量的组件。 当然,如果习惯将部件都写在widget.py中,也是可以的,但这样一来, 如果页面上有很多个checkbox需要替换时, 页面代码中就会有很多段 <script …… </script>, 不那么美观。

以上是 2022年11月,我在回答群友问题时整理的。

2025/9/13 于北京/上东廓

这篇文章有用吗?

点击星号为它评分!

平均评分 0 / 5. 投票数: 0

到目前为止还没有投票!成为第一位评论此文章。

很抱歉,这篇文章对您没有用!

让我们改善这篇文章!

告诉我们我们如何改善这篇文章?

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注