Django ModelForm是否将未指定的字段设置为空?

时间:2012-02-13 19:18:49

标签: django django-forms

我的模型看起来像:

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!

这是预期的行为吗?我如何更改这一点,以便我可以确保如果在表单中未指定字段,但实例中是否已存在未用空字符串覆盖的字段?

3 个答案:

答案 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='')