django中使用基于BaseForm统一对BootStrap样式优化组件

使用Form或者ModelForm时可以统一对BootStrap样式优化

预备知识

mro

super().__init__():不是执行父类中的__init__方法,而是按照类的MRO(类的继承关系,Method Resolution Order)顺序,从下往上执行,可以通过==类名.mro()或者类名.__mro__==得到该类的继承关系。

Form/ModelForm继承和字段收集过程

在 Django 的 BaseForm 类中,base_fields 属性确实是在 __init__ 方法中被深拷贝到 self.fields 的,但在深拷贝之前,base_fields 属性实际上已经通过继承链被设置好了。

BaseForm 本身不直接定义任何字段,但它作为一个基类,可以被子类继承。当你创建一个继承自 BaseForm 的子类时(例如 forms.Formforms.ModelForm),子类可以定义自己的字段。这些字段定义是通过 Django 的 DeclarativeFieldsMetaclass 元类在类定义时自动收集的。

这里是继承和字段收集过程的简化示例
  1. DeclarativeFieldsMetaclass - 这是一个元类,负责在类定义时收集所有字段声明,并将它们存储在 declared_fields 属性中。

  2. Form (继承自 BaseForm) - 这是一个具体的表单类,使用 DeclarativeFieldsMetaclass 作为其元类。当你在 Form 类中定义字段时,这些字段被 DeclarativeFieldsMetaclass 收集,并最终存储在 base_fields 属性中。

  3. BaseForm - 这个类提供了表单的基础架构,包括 __init__ 方法,该方法创建 self.fields 的深拷贝。由于 BaseForm 是一个基类,它不定义 base_fields,而是由其子类在元类的辅助下定义。

所以,当你创建一个表单实例时,例如 MyForm(),Django 首先使用 DeclarativeFieldsMetaclass 来处理类定义,收集所有字段声明,并设置 base_fields。然后,当你实例化 MyForm 时,BaseForm__init__ 方法被调用,它深拷贝 base_fieldsself.fields,为表单实例创建一个字段的独立副本。

这是 BaseForm__init__ 方法的一个片段,展示了 self.fields 是如何从 base_fields 创建的:

class BaseForm:
    # ...

    def __init__(self, data=None, files=None, *args, **kwargs):
        # ... 省略了其他初始化代码 ...

        # Instances should always modify self.fields; they should not modify
        # self.base_fields.
        self.fields = copy.deepcopy(self.base_fields)

        # ... 省略了其他初始化代码 ...

在这个示例中,self.base_fields 是在类定义时通过元类设置的,然后在实例化时被深拷贝到 self.fields这样,每个表单实例都有自己的字段副本,而不会相互影响。

在这里插入图片描述

在这里插入图片描述

多继承来简化对统一样式的处理

class BootStrapForm:
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)

        # {'title':对象,"percent":对象}
        for name, field in self.fields.items():
            field.widget.attrs['class'] = "form-control"
            field.widget.attrs['placeholder'] = "请输入{}".format(field.label)

使用

from django.shortcuts import render, redirect
from web import models
from django import forms
from django.urls import reverse
from ... import BootStrapForm

class LevelForm(BootStrapForm, forms.Form):
    title = forms.CharField(
        label="标题",
        required=True,
    )
    percent = forms.CharField(
        label="折扣",
        required=True,
        help_text="填入0-100整数表示百分比,例如:90,表示90%"
    )


class LevelModelForm(BootStrapForm, forms.ModelForm):
    class Meta:
        model = models.Level
        fields = ['title', 'percent']
        
levelmodelform = LevelModelForm()  # ['BootStrapForm','forms.ModelForm','BaseModelForm','BaseForm']
levelform = LevelForm()  # ['BootStrapForm','BaseModelForm','BaseForm']

若有错误与不足请指出,关注DPT一起进步吧!!!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

叫我DPT

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值