2012-09-03 36 views
3

在一個窗體中,我將MultiValueField(MVF)與具有多個字段的MultiWidget一起使用。如果在MVF領域的一個驗證錯誤,這被處理(顯示)在MVF的水平,而不是在各個子場,這可能會導致:如何在每個字段的MultiValueField/MultiWidget中呈現驗證錯誤

* Ensure this value is greater than or equal to 1. 
* Ensure this value is greater than or equal to -100.0. 

Number of days: -1 
... 
... 
Threshold: -200 

當第一錯誤是指MVF的第一個字段,第二個錯誤是MVF的最後一個字段。

是否有可能將這些錯誤消息「MVF」放在他們所屬的領域? (也許在MultiWidget的format_output方法?)

+0

您是否找到解決方案? –

+0

不,我沒有,我仍然需要一個。顯然這個問題並沒有引起很多關注...... –

+0

好吧,我目前面臨同樣的問題。問題在於錯誤呈現在表單級別,並且不會分派到字段,在此級別,MVF呈現爲單個HTML塊,並且僅_after_是附加的錯誤消息。而且,'AssertionError'是用MVF名字記錄的,所以我們不知道哪個子字段引發了它。如果我解決了這個問題,我會告訴你,希望不要修補Django! –

回答

0

下面的解決方案不使用MultiValueField而是:

  • 動態與幾個替換原有的形式的__init__
  • 重構有效數據的原始場對於表單驗證期間_post_clean

這裏原始字段是一些需要被適於每種情況下的測試代碼:

class MyMultiField(CharField): 

    def split(self, form): 
     name = 'test' 
     form.fields_backup[name] = form.fields[name] 
     del form.fields[name] 
     # here is where you define your individual fields: 
     for i in range(3): 
      form.fields[name + '_' + str(i)] = CharField() 
      # you need to extract the initial data for these fields 
      form.initial[name + '_' + str(i)] = somefunction(form.initial[name]) 
     form.fields['test_1'] = DecimalField() # because I only want numbers in the 2nd field 

    def restore(self, form): 
     # here is where you describe how to joins the individual fields: 
     value = ''.join([unicode(v) for k, v in form.cleaned_data.items() if 'test_' in k]) 
     # extra step to validate the combined value against the original field: 
     try: 
      restored_data = form.cleaned_data.copy() 
      restored_data["test"] = form.fields_backup["test"].clean(value) 
      for k in form.cleaned_data: 
       if k.startswith("test_"): 
        del restored_data[k] 
      form.cleaned_data = restored_data 
     except Exception, e: 
      form._errors[NON_FIELD_ERRORS] = form.error_class(e) 


class MyForm(Form): 

    test = MyMultiField() 

    def __init__(self, *args, **kwargs): 
     super(ItemForm, self).__init__(*args, **kwargs) 
     self.fields_backup = {} 
     self.fields['data'].split(self) 

    def _post_clean(self): 
     self.fields_backup['data'].restore(self) 
     return super(MyForm, self)._post_clean() 

前:

(驗證某些輸入)後:

multifield

我不知道是否有可能進一步分離這個字段/表單代碼使用這種方法。我對這段代碼也不太滿意,因爲新的字段類需要從原始類繼承。

儘管如此,其基本思想是存在的,我成功地用它從存儲在PostgreSQL的hstore單一車型領域的詞典內置單獨驗證表單字段。

相關問題