2012-02-13 60 views
2

我有一個模型,看起來像:Django ModelForm是否將未指定的字段設置爲空?

class MyModel(Model): 
    name = models.TextField(blank=True, default='') 
    bio = models.TextField(blank=True, default='') 

和看起來像一個的ModelForm:

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! 

這是預期的行爲?我如何改變這一點,以便我可以確保如果表單中沒有指定一個字段,但是它已經存在於實例中,它沒有被空字符串覆蓋?

回答

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) 
+0

謝謝!當我有動態模型時,防止意外覆蓋數據的好主意 – 2013-03-13 00:52:02

+0

data.update(request.POST.dict()) – 2014-08-31 11:33:29

+0

@Gromish我做了一個快速測試,對於多關係的我來說,它似乎工作正常。你可能會更好地提出一個新問題,而不是在這裏留言,因爲更多的人會看到它。 – Alasdair 2015-02-11 14:48:14

0

如果你想初始數據傳遞到形式,使用的初始代替數據

MyModelForm(instance=my_model, initial={'bio': 'this is me'}) 
          ^

[編輯]

如果已經包含在您的形式爲名稱的字段

fields = ('name', 'bio') 

但是不通過任何「姓名」的數據

data={'bio': 'this is me'} 

表單字段的行爲就好像名稱已經空白。

這是允許在你的模型,所以is_valid()將是真正的

name = models.TextField(blank=True, default='') 
+0

我沒有試圖傳遞*初始*數據 - 這是我試圖驗證窗體的數據。 (我通過JSON獲取它)。 – 2012-02-13 19:50:06

1

提供了instance參數爲ModelForm是一樣的傳球initial,即,它們服務於同一目的。得到保存的是總是data。如果該字典中的某個字段爲空,則該模型也會保存。

如果你想保持整個模型的狀態,只處理單個字段爲data。然後,你可以試試下面的:

data = my_model.__dict__ 
data['bio'] = request.POST.get('bio') 
MyModelForm(instance=my_model, data=data) 
相關問題