我的模型看起来像:
class MyModel(Model):
name = models.TextField(blank=True, default='')
bio = models.TextField(blank=True, default='')
和一个看起来像的模型形式:
class MyModelForm(ModelForm):
class Meta:
model = MyModel
fields = ('name', 'bio')
当我像这样创建/初始化我的表单时:
form = MyModelForm(instance=my_model, data={'bio': 'this is me'}) # where my_model has a name already set
然后:
form.is_valid() # evaluates to true
form.save() # overwrites the name field in my_model and makes it blank!
这是预期的行为吗?我如何更改这一点,以便我可以确保如果在表单中未指定字段,但实例中是否已存在未用空字符串覆盖的字段?
答案 0 :(得分:8)
请注意,Django仅将name
字段设置为空,因为您已设置blank=True
。如果需要该字段,则会出现验证错误。
最近django-developers组有一个关于改变这种行为的discussion。核心开发者阿德里安和保罗赞成目前的行为。
因此,如果您要将此视图的模型表单与使用blank = True的模型一起使用,则需要在数据字典中包含所有模型字段。您可以使用函数model_to_dict
。
from django.forms.models import model_to_dict
data = model_to_dict(my_model)
data.update({'bio': 'this is me'}) # or data.update(request.POST)
form = MyModelForm(instance=my_model, data=data)
答案 1 :(得分:2)
向instance
提供ModelForm
参数与传递initial
相同,即它们用于相同目的。保存的内容是总是 data
。如果该字典中的字段为空,那么也将保存模型。
如果只想将单个字段作为data
处理,则要保持模型的整个状态。然后,尝试以下内容:
data = my_model.__dict__
data['bio'] = request.POST.get('bio')
MyModelForm(instance=my_model, data=data)
答案 2 :(得分:0)
如果要将初始数据传递给表单,请使用initial而不是data
MyModelForm(instance=my_model, initial={'bio': 'this is me'})
^
[编辑]
如果您在表单中包含了名称字段
fields = ('name', 'bio')
但不传递“name”的任何数据
data={'bio': 'this is me'}
表单字段的行为就像名称已提交为空白一样。
您的模型允许哪种,因此is_valid()将为True
name = models.TextField(blank=True, default='')