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一起进步吧!!!

相关推荐
向左转, 向右走ˉ3 分钟前
PyTorch随机擦除:提升模型抗遮挡能力
人工智能·pytorch·python·深度学习
马特说15 分钟前
金融时间序列机器学习训练前的数据格式验证系统设计与实现
python·机器学习·金融
Blue桃之夭夭15 分钟前
基于OpenCV的实时人脸检测系统实现指南 ——Python+Haar级联分类器从环境搭建到完整部署
人工智能·python·opencv
偷偷的卷16 分钟前
【算法笔记 day three】滑动窗口(其他类型)
数据结构·笔记·python·学习·算法·leetcode
木头左18 分钟前
决策树与随机森林Python实践
python·随机森林
网小鱼的学习笔记32 分钟前
python中MongoDB操作实践:查询文档、批量插入文档、更新文档、删除文档
开发语言·python·mongodb
Q_Q51100828542 分钟前
python的保险业务管理与数据分析系统
开发语言·spring boot·python·django·flask·node.js·php
王小王-1231 小时前
基于Python的程序员数据分析与可视化系统的设计与实现
python·数据挖掘·数据分析·招聘数据分析·程序员数据分析·招聘薪资数据分析·智联招聘可视化
昀贝1 小时前
Maven项目引用本地jar涉及scope和systemPath配置
python·maven·jar