如何对modelform进行子类化(使用模型中的额外字段进行扩展)?

时间:2011-06-30 21:11:01

标签: python django django-forms

我有一个模型和表格:

class MyModel(models.Model):
    field_foo = models.CharField(_("Foo"), max_length=50)
    field_bar = models.IntegerField(_("Bar"))

class MyFormOne(forms.ModelForm):
    class Meta:
        model=MyModel
        fields = ('field_foo', )
        widgets = {'field_foo': forms.TextInput(attrs={'size': 10, 'maxlength': 50}),}

我希望有另一种形式MyFormTwo,它还可以通过包含字段field_bar来对该表单进行子类化。我的观点是不必在第二种形式(DRY原则)中重复field_foo的小部件声明,也不必重复MyFormOne中的字段列表(实际上还有更多然后是上面简单例子中的一个字段。

我应该如何定义MyFormTwo

3 个答案:

答案 0 :(得分:3)

您不必显式声明整个小部件,只需修改不同的attrs即可。 或者,如果您在实际代码中有自定义小部件,我会

  1. 创建一个自定义模型字段类,默认情况下使用该窗口小部件,如果它是一般条件,那么在表单类中它只是“自动”工作。
  2. 如果它只是特定于表单(不是模型特定的),那么对于那种情况,我只是在Form类上显式声明表单字段,而不是在Meta中,然后继承以直接的方式应用。
  3. 但是使用默认小部件(使用自定义attrs)我会尝试类似下面的内容

    class MyModel(models.Model):
        field_foo = models.CharField(_("Foo"), max_length=50)
        field_bar = models.IntegerField(_("Bar"))
    
    class MyFormOne(forms.ModelForm):
        class Meta:
            model=MyModel
            fields = ('field_foo', )
    
        def __init__(*args, **kwargs):
            super(MyFormOne, self).__init__(*args, **kwargs)
    
            self.fields['field_foo'].widget.attrs['size'] = 10
            # max_length should already be set automatically from model
            # TextInput is also default widget for CharField
    
    class MyFormTwo(MyFormOne):
        class Meta:
            model=MyModel
            fields = MyFormOne.Meta.fields + ('field_foo2',)
    
        def __init__(*args, **kwargs):
            super(MyFormTwo, self).__init__(*args, **kwargs)
    
            self.fields['field_foo2'].widget.attrs['size'] = 10
    

答案 1 :(得分:2)

我不确定这是否有用(它完全没有使用Django表格/模型),但是如果它确实让我知道。

class MyModel(models.Model):
    field_foo = models.CharField(_("Foo"), max_length=50)
    field_bar = models.IntegerField(_("Bar"))

class MyFormOne(forms.ModelForm):
    class Meta:
        model=MyModel
        fields = ('field_foo', )
        widgets = {'field_foo': forms.TextInput(attrs={'size': 10, 'maxlength': 50}),}

class MyFormTwo(MyFormOne):
    class Meta(MyFormOne.Meta):
        fields = MyFormOne.Meta.fields + ('field_foo2',)
        widgets = MyFormOne.Meta.widgets
        # Add new fields as a dictionary
        widgets.update({'field_foo2': forms.TextInput(attrs={'size': 10, 'maxlength': 50}),)
        # Or add them one by one
        widgets['field_foo3'] = forms.TextInput(attrs={'size': 10, 'maxlength': 50})

同样,我不知道这是否会对你有所帮助。请告诉我你得到的结果。

答案 2 :(得分:0)

这段代码有点陈旧,但它解释了我能够获得多重继承的唯一方法。这很难看。

http://djangosnippets.org/snippets/703/

还有一张关于它的开放票:https://code.djangoproject.com/ticket/7018