这是一个对我有用的解决方案。
# 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 的值从cleaned_data 分配给实例的field_B。请记住,您应该在此之前致电form.is_valid()。否则将没有cleaned_data。
if commit:
instance.save()
如果用户希望将实例保存到数据库中,请执行此操作。
return instance
最后,返回实例。
示例用法
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]: