2010-02-10 20 views
14

如何在清除數據後向表單頂部添加錯誤?我有一個對象需要對外部應用程序(谷歌地圖)進行REST調用作爲預保存條件,這可能會失敗,這意味着我需要我的用戶更正表單中的數據。所以我清理的數據,然後嘗試保存並添加到窗體錯誤如果保存不起作用:向Django表單錯誤添加錯誤.__ all__

if request.method == "POST": 
#clean form data 
    try: 
     profile.save() 
     return HttpResponseRedirect(reverse("some_page", args=[some.args])) 
    except ValueError: 
     our_form.errors.__all__ = [u"error message goes here"] 
return render_to_response(template_name, {"ourform": our_form,}, 
     context_instance=RequestContext(request)) 

這未能返回我的單元測試的錯誤文本(這是在尋找它{{form.non_field_errors}}),然後當我通過調試器運行時,當它們到達render_to_response行時,錯誤沒有被添加到窗體錯誤字典中,也沒有添加到our_form樹中的任何其他位置。爲什麼這不工作?如何在清理後將錯誤添加到表單頂部?

回答

9

您應該提出驗證錯誤。

爲什麼不把驗證形式的清潔方法

class ProfileForm(forms.Form): 
    def clean(self): 
     try: 
      #Make a call to the API and verify it works well 
     except: 
      raise forms.ValidationError('Your address is not locatable by Google Maps') 

內的方式,你只需要標準form.is_valid()在視圖中。

+1

不幸的是,它必須更加系統化,當系統的其他部分試圖更改數據時,可能會發生此更新,因此它不僅僅是一種形式。 否則,你是對的,表單將是理想的。 – hendrixski 2010-03-04 03:48:02

+0

不應該總是使用繼承的表單來進行驗證嗎? – 2012-05-07 09:47:08

18

你真的想在表單驗證過程中這樣做,並從那裏引發一個ValidationError ......但是如果你這樣做,你會想要訪問_errors來添加新消息。嘗試是這樣的:

from django.forms.util import ErrorList 

our_form._errors["field_name"] = ErrorList([u"error message goes here"]) 
+0

我需要在表單頂部的錯誤,因爲它不是任何一個領域,會導致這種失敗(例如,我結合街道+城市+州+郵政編碼和地理編碼)。 – hendrixski 2010-02-10 17:01:49

+6

-1,因爲這沒有解決OP添加*非字段*錯誤的要求。也是-1,因爲這個賦值消除了'_errors [「field_name」]''已經存在的任何錯誤。 – JCotton 2012-07-20 18:19:43

+0

這會是一個正確的方法嗎?自助._errors ['field_name'] = self._errors.get('field_name',[]) self._errors ['field_name'] = self._errors ['field_name']。append( _(「field_name is invalid」) #add anyy non-field error raise form.ValidationError(non_field_errors) – 2013-03-28 10:00:52

1

我不知道一個黑客多麼可怕,這是(我只真正在兩個工作的Django項目,直到這一點),但如果你這樣做遵循你得到一個未在該模型與特定字段相關聯的單獨錯誤消息:

form = NewPostForm() 
if something_went_horribly_wrong(): 
    form.errors[''] = "You broke it!" 
12
可以使用恆定 NON_FIELD_ERRORS字典鍵(這是 __all__默認情況下)被加入

非字段錯誤:

from django import forms 
errors = my_form._errors.setdefault(forms.forms.NON_FIELD_ERRORS, forms.util.ErrorList()) 
errors.append("My error here") 
+2

這導致'NoneType'對象沒有屬性'setdefault'對我來說可能我的模型是有效的,因此_errors is undefined。任何想法? – 2011-01-22 17:02:20

+0

Worked well for me。謝謝! – urig 2011-08-25 14:10:46

+2

@MartinProbst:調用form.is_valid()後必須運行此代碼 – 2012-11-07 10:31:45

8

您幾乎與您的原始解決方案。這裏是一個基窗體類我建,讓我做同樣的事情,即添加非現場錯誤消息的形式:

from django import forms 
from django.forms.util import ErrorDict 
from django.forms.forms import NON_FIELD_ERRORS 

class MyBaseForm(forms.Form): 
    def add_form_error(self, message): 
     if not self._errors: 
      self._errors = ErrorDict() 
     if not NON_FIELD_ERRORS in self._errors: 
      self._errors[NON_FIELD_ERRORS] = self.error_class() 
     self._errors[NON_FIELD_ERRORS].append(message) 

class MyForm(MyBaseForm): 
    .... 

我所有的形式擴展這個類,所以我可以簡單地調用add_form_error( )方法添加另一個錯誤消息。

+0

用於檢查屬性是否存在並且不假設'error_class()'是一個ErrorList。你可以使用這種方法來追加非字段錯誤消息,而不需要su bclassing表單,這可能適合其他用例。 – JCotton 2012-07-20 18:12:58

+0

1.7有這樣的內置。 – 2014-10-06 23:01:07

0

如果驗證屬於數據層,那麼您應該確實不使用表單驗證。但是從Django 1.2開始,Django模型存在類似的概念,這當然是你應該使用的。見the documentation for model validation

10

在Django的1.7或更高版本,我會做:

form.add_error(field_name, "Some message") 

的方法add_error在1.7加入。 form變量是我想操作的表單,而field_name是特定字段名稱,或者None,如果我想要一個與特定字段無關的錯誤。

在Django 1。6我會做這樣的事情:

from django.forms.forms import NON_FIELD_ERRORS 

errors = form._errors.setdefault(field_name, form.error_class()) 
errors.append("Some message") 

在上面form的代碼是我想操縱和field_name是我想添加一個錯誤的字段名的形式。 field_name可以設置爲NON_FIELD_ERRORS,以添加與特定字段無關的錯誤。我使用form.error_class()來生成錯誤消息的空列表。這就是Django 1.6在內部創建一個空列表而不是直接實例化ErrorList()

+0

嘿路易斯,非常感謝你這個答案,太棒了! – 2015-05-26 12:55:27

+0

@Louis,我的是1.8,我試過「form.add_error(field_name,」Some message「)」,然後它報告「'MyForm'對象沒有屬性'addError'」,我是否需要導入除「from django.core.exceptions導入ObjectDoesNotExist,ValidationError「? – 2015-11-04 01:54:43