在处理之前更改Django表单数据

时间:2010-09-29 02:37:27

标签: django django-forms

我有一个模型的表单,它有两个字段:field_A和field_B。我想:

  • 呈现表单时:仅显示field_A
  • 当我调用form.save()时,field_B保存在模型中,其值为field_A

我尝试了什么:

field_A = forms.CharField(required=True)
field_B = forms.CharField(required=False)

def save(self, *args, **kwargs):
     """
     Overriding save, so call the parent form save and return the new_user
     object.
     """
     self.data["field_B"] = self.data["field_A"]
     self.cleaned_data["username"] = self.cleaned_data["email"]
     super(MyParentClass*, self).save(*args, **kwargs) 

*这两个字段都是从ParentClass继承的,需要它们

1 个答案:

答案 0 :(得分:5)

这是一个适合我的解决方案。

# 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

表单Meta

的说明
exclude = ('field_B',)

确保满足您的第一个条件。向用户显示表单时,仅显示field_A。第二个条件在重写的save()方法中解决。

save()

的说明
commit = kwargs.pop('commit', True)

提供commit关键字参数(如果提供)。

instance = super(MyModelForm, self).save(*args, commit = False, **kwargs)

创建基础模型的实例。显式传递commit=False以确保此实例尚未保存到数据库中。

instance.field_B = self.cleaned_data['field_A']

field_A的{​​{1}}值分配给实例的cleaned_data。请记住,在此之前您应该调用field_B。否则将没有form.is_valid()

cleaned_data

如果用户希望将实例保存到数据库,那么就这样做。

        if commit:
            instance.save()

最后,返回实例。

样本使用

return instance