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

相关推荐
drebander1 小时前
使用 Java Stream 优雅实现List 转化为Map<key,Map<key,value>>
java·python·list
威威猫的栗子1 小时前
Python Turtle召唤童年:喜羊羊与灰太狼之懒羊羊绘画
开发语言·python
墨染风华不染尘2 小时前
python之开发笔记
开发语言·笔记·python
Dxy12393102162 小时前
python bmp图片转jpg
python
麦麦大数据2 小时前
Python棉花病虫害图谱系统CNN识别+AI问答知识neo4j vue+flask深度学习神经网络可视化
人工智能·python·深度学习
LKID体2 小时前
Python操作neo4j库py2neo使用之创建和查询(二)
数据库·python·neo4j
LKID体2 小时前
Python操作neo4j库py2neo使用之py2neo 删除及事务相关操作(三)
开发语言·python·neo4j
小屁孩大帅-杨一凡2 小时前
Python-flet实现个人视频播放器
开发语言·python·音视频
算家云2 小时前
快速识别模型:simple_ocr,部署教程
开发语言·人工智能·python·ocr·数字识别·检测模型·英文符号识别
Thomas_Cai2 小时前
Python后端flask框架接收zip压缩包方法
开发语言·python·flask