如何在子类中从父表单中移除字段?

45 投票
4 回答
26853 浏览
提问于 2025-04-17 19:56
class LoginForm(forms.Form):
    nickname = forms.CharField(max_length=100)
    username = forms.CharField(max_length=100)
    password = forms.CharField(widget=forms.PasswordInput)


class LoginFormWithoutNickname(LoginForm):
    # i don't want the field nickname here
    nickname = None #??

有没有办法做到这一点?

注意:我没有使用 ModelForm,所以带有 excludeMeta 类不管用。

4 个回答

5

我发现了这个,如果感兴趣请留言。

(在Django 1.7.4中)

扩展表单,使用以下代码:

class MyForm(forms.ModelForm):

    def __init__(self, *args, **kwargs):
        super(MyForm, self).__init__(*args, **kwargs)

        for key, field in self.fields.iteritems():
            self.fields[key].required = False

    class Meta:
        model = MyModel
        exclude = []

    field_1 = forms.CharField(label="field_1_label")
    field_2 = forms.CharField(label="field_2_label", widget=forms.Textarea(attrs={'class': 'width100 h4em'}),)
    field_3 = forms.CharField(label="field_3_label", widget=forms.TextInput(attrs={'class': 'width100'}),)
    field_4 = forms.ModelChoiceField(label='field_4_label', queryset=AnotherModel.objects.all().order_by("order") )

class MyForm_Extended_1(MyForm):
    field_1 = None


class MyForm_Extended_2(MyForm):
    class Meta:
        model = MyModel
        exclude =[
                    'field_1',
                ]

MyForm_Extended_1把field_1设置为None,(数据库中的这一列被更新为Null)

MyForm_Extended_2则忽略这个字段(在保存时忽略数据库中的这一列)

所以,针对我的需求,我选择了第二种方法。

13

Django 1.7 在一个更新中解决了这个问题,具体可以查看这个提交记录 b16dd1fe019,对应的票据是 #8620。在 Django 1.7 中,正如提问者所说,可以在子类中使用 nickname = None。根据这个更新的文档内容:

可以通过“遮蔽”父类中的 Field 来选择不使用它。虽然任何非 Field 的值都可以达到这个目的,但建议使用 None,这样可以明确表示这个字段被设置为无效。

79

你可以通过重写init方法来改变子类中的字段:

class LoginFormWithoutNickname(LoginForm):
    def __init__(self, *args, **kwargs):
        super(LoginFormWithoutNickname, self).__init__(*args, **kwargs)
        self.fields.pop('nickname')

撰写回答