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 创建的:

python 复制代码
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。这样,每个表单实例都有自己的字段副本,而不会相互影响。

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

python 复制代码
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)

使用

python 复制代码
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一起进步吧!!!

相关推荐
小白勇闯网安圈1 小时前
Django 响应对象、文件上传与类视图
数据库·django·sqlite
从零开始学习人工智能1 小时前
【踩坑实录】WSL2 解决 onnxruntime\-gpu ImportError: libcudart\.so\.13 无 CUDA13 运行库问题
python
卷无止境3 小时前
在 awesome-fastapi 里,哪些库值得一看?
后端·python
zhanghaha13143 小时前
Python进阶教程:6_JSON 数据解析 —— 新手完全指南
开发语言·python·json
Python私教3 小时前
API 输出模型怎么设计:从 model_dump() 到显式展示层
python·fastapi
Python私教4 小时前
本地 AI 工具服务该绑定 127.0.0.1 还是 0.0.0.0?
python·fastapi
卷无止境4 小时前
FastAPI 的Admin面板生态
后端·python
ctlover4 小时前
Streamlit 框架
python
ι:5 小时前
MATLAB 与 Python 搭建无人机地面站:优势、劣势与选型逻辑
python·matlab·无人机
船厂电气自动化ai大模型5 小时前
AI大模型与数学 第32课 函数凹凸性与二阶导数:拐点求解、凹凸区间计算(10道二阶导数计算题)
数据结构·人工智能·python·深度学习·算法