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
,所以带有Meta
的exclude
类不起作用。
您可以通过覆盖init方法来更改子类中的字段:
class LoginFormWithoutNickname(LoginForm):
def __init__(self, *args, **kwargs):
super(LoginFormWithoutNickname, self).__init__(*args, **kwargs)
self.fields.pop('nickname')
Django 1.7在提交b16dd1fe019的票证#8620中解决了此问题。在Django 1.7中,可以按照OP的建议在子类中执行nickname = None
。从文档更改中提交:
可以通过遮挡从父类继承的
Field
中退出。尽管任何非Field
值都可用于此目的,但建议使用None
使其明确表明字段已无效。
我发现了,如果有兴趣请发表评论。
(在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将字段_1设置为无,(数据库中的列更新为空)
MyForm_Extended_2忽略该字段(在保存期间忽略db中的列)
因此,出于我的目的,我使用第二种方法。
[我不喜欢这样的事实(或我理解),使用“类元:”排除第二类中的字段仍然会导致未使用的字段位于数据库中。
也许最简单的方法是定义一个抽象类,该抽象类具有两个类共享的字段。然后,上面的两个原始类成为该新类的子类。因此,在该线程开始时给出的示例可能如下所示。这是更多的代码,但是通过这种方式,您可以扩展子类,而不是从超类中进行(不完整的)排除。
class LoginForm_Common(forms.Form):
username = forms.CharField(max_length=100)
password = forms.CharField(widget=forms.PasswordInput)
class Meta:
abstract = True
class LoginForm(LoginForm_Common):
nickname = forms.CharField(max_length=100)
class LoginFormWithoutNickname(LoginForm_Common):
pass