Voici une solution qui a fonctionné pour moi.
# models.py
class MyModel(models.Model):
field_A = models.CharField(max_length = 255)
field_B = models.CharField(max_length = 255)
def __unicode__(self):
return "%s: %s, %s" % (self.pk, self.field_A, self.field_B)
# forms.py
class MyModelForm(ModelForm):
class Meta:
model = MyModel
exclude = ('field_B',)
def save(self, *args, **kwargs):
commit = kwargs.pop('commit', True)
instance = super(MyModelForm, self).save(*args, commit = False, **kwargs)
instance.field_B = self.cleaned_data['field_A']
if commit:
instance.save()
return instance
Explication des Meta
exclude = ('field_B',)
assure que votre première condition de la forme est remplie. Lorsque le formulaire est affiché à l'utilisateur, seul le message field_A
est affiché. La deuxième condition est traitée dans la méthode save()
remplacée.
Explication des save()
commit = kwargs.pop('commit', True)
Extrait l'argument mot-clé commit
si fourni.
instance = super(MyModelForm, self).save(*args, commit = False, **kwargs)
Créez une instance du modèle sous-jacent. Passez explicitement commit=False
pour vous assurer que cette instance n'est pas encore enregistrée dans la base de données.
instance.field_B = self.cleaned_data['field_A']
affecter la valeur de field_A
cleaned_data
-field_B
de l'instance. Rappelez-vous que vous devriez avoir appelé form.is_valid()
avant cela. Sinon, il n'y aura pas de cleaned_data
. Si l'utilisateur souhaite que l'instance soit enregistrée dans la base de données, faites-le.
return instance
Enfin, renvoyez l'instance.
Exemple d'utilisation
In [1]: from app.forms import MyModelForm
In [2]: f = MyModelForm(data = {'field_A': 'Value A'})
In [3]: f.is_valid()
Out[3]: True
In [4]: f.save()
Out[4]: <MyModel: 3: Value A, Value A>
In [5]: f = MyModelForm(data = {'field_A': 'VA'})
In [6]: f.is_valid()
Out[6]: True
In [7]: f.save(commit = False)
Out[7]: <MyModel: None: VA, VA>
In [8]:
ajouté informations pour modifier – Victor