【问题标题】:Django form how to create a simple mixinDjango表单如何创建一个简单的mixin
【发布时间】:2026-02-12 01:10:02
【问题描述】:

我有一组引用单个模型的特殊形式,我定义了一个通用的:

class myBaseFormMixin(forms.Form):    
    data_prod = forms.DateField(initial=datetime.date.today, label='Data')

    class Meta:
     model = mymodel

    def clean(self):
        if self.data["a"]=='off':  
          raise forms.ValidationError("check A")

然后以我的特殊形式添加:

class SpecialManForm(forms.ModelForm,myBaseFormMixin)
 def __init__(self, *args, **kwargs):
        super(SpecialManForm, self).__init__(*args, **kwargs)
        self.helper = FormHelper()
        self.helper.layout = Layout(

            Fieldset(
                'Description',
                Row(
                Div('field_a', css_class='large-3 columns '),
                ),
            ),

显然一切都很好,Meta Mixin 中模型中的所有字段都可用,但是 mixin 中的 clean() 没有执行,如果我将 def clean() 附加到 SpecialManForm,为什么会这样?

我错过了什么吗?提前致谢

【问题讨论】:

    标签: django forms mixins django-crispy-forms


    【解决方案1】:

    您应该更改您的 SpecialManForm 以便它首先使用您的 mixin。

    class SpecialManForm(myBaseFormMixin, forms.ModelForm)
        def __init__(self, *args, **kwargs):
            ....
    

    当python在寻找clean方法时,它会首先检查SpecialManForm类,它没有被实现。然后它将通过继承层次结构,这意味着首先检查 ModelForm(正如您目前拥有的那样)。它在那里实现,因此它将使用来自 ModelForm 的代码,而不是来自你的 mixin,并执行它。

    更改类定义中的顺序意味着它将在 ModelForm 类之前检查您的 mixin 是否有 clean 方法,并使用您已实现的方法。

    它按以下顺序检查(您的版本) SpecialManForm -> ModelForm -> myBaseFormMixin,这解释了为什么当您将方法添加到 SpecialManForm 时它会起作用。

    【讨论】:

      【解决方案2】:

      我已经解决了继承问题:

      class myBaseFormMixin(forms.ModelForm):  
      

      然后是特殊形式:

      class SpecialManForm(myBaseFormMixin)
      

      【讨论】:

      • 所以你有一个现在实际上不需要的额外类。
      • 为什么这么说?只有一个类被用作其他类的基础......所以:SpecialManForm -> ModelForm -> myBaseFormMixin,变成了 SpecialManForm -> myBaseFormMixin
      • 好吧,您确实问过如何使用 mixins,这就是我的回答向您展示的方法。它们有效地完成了同样的事情,但我的解决方案使用更少的代码并创建了更少的类。
      • 感谢您的解释,我想我应该在文档中进行更多搜索以了解哪个是最好的,mixin 或继承。祝你有美好的一天
      • 如果您实际上不打算创建 myBaseFormMixin 的实例,那么 mixins 可能更合适。虽然这两种方法非常相似。