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 #??
Existe-t-il un moyen d'y parvenir?
Remarque: je n'ai pas de ModelForm
, donc la classe Meta
avec exclude
ne fonctionne pas.
Vous pouvez modifier les champs d'une sous-classe en remplaçant la méthode init:
class LoginFormWithoutNickname(LoginForm):
def __init__(self, *args, **kwargs):
super(LoginFormWithoutNickname, self).__init__(*args, **kwargs)
self.fields.pop('nickname')
Django 1.7 a résolu ce problème dans commit b16dd1fe019 pour le ticket # 862 . Dans Django 1.7, il devient possible de faire nickname = None
dans la sous-classe comme le suggère le PO. D'après les modifications de la documentation dans le commit:
Il est possible de se désengager d'une
Field
héritée d'une classe parente en l'observant. Bien que toute valeur nonField
fonctionne à cet effet, il est recommandé d'utiliserNone
pour indiquer explicitement qu'un champ est en cours d'annulation.
J'ai trouvé cela, veuillez commenter si vous êtes intéressé.
(dans Django 1.7.4) formulaires étendus, avec le code suivant:
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 définissez field_1 sur None, (la colonne dans db est mise à jour sur Null)
MyForm_Extended_2 ignore le champ (ignore la colonne dans db lors de la sauvegarde)
Donc, pour mon but, j'utilise la deuxième méthode.
Je n'ai pas aimé le fait (ou du moins j'ai compris) que l'exclusion d'un champ dans la deuxième classe en utilisant "classe Meta:" entraîne toujours le champ inutilisé dans la base de données.
Le moyen le plus simple est peut-être de définir une classe abstraite dont les champs sont partagés par les deux classes. Ensuite, les deux classes originales ci-dessus deviennent des sous-classes de cette nouvelle classe. Ainsi, l'exemple donné au début de ce fil pourrait ressembler à ceci. C'est un peu plus de code, mais de cette façon, vous étendez une sous-classe plutôt que de faire une exclusion (incomplète) d'une super classe.
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