2013-05-09 10 views
11

テンプレート内の{{form.errors}}を使用して、すべてのフォームエラーをまとめてリストしたいと思います。フォームフィールドのリストと、各フィールドのエラーのネストされたリストが生成されます。ただし、フィールドのリテラル名が使用されます。特定のフィールドでエラーが発生したhtmlは次のようになります。フィールド名ではなくラベルでフォームエラーをレンダリングする

<ul class="errorlist"> 
    <li> 
     target_date_mdcy 
     <ul class="errorlist"> 
      <li>This field is required.</li> 
     </ul> 
    </li> 
</ul> 

私はエラーリスト機能を使いたいと思います。しかし、フィールド名ではなく、ラベル( "Target Date")を使用したいと思います。実際には、Webページのユーザーにフィールド名を表示させたいというケースは考えられません。レンダリングされたエラーリストをフィールドラベルと共に使用する方法はありますか?

答えて

9

私はこれを行う簡単な方法はありません。

フォームのエラーの属性は、実際に、django.forms.utilsで定義されたクラスをErrorDict返します - それはそのUnicode表現として自分自身のことulのレンダリングを生成するために知っているdictのサブクラスです。しかし、キーは実際にフィールド名であり、それは他の動作を維持するために重要です。したがって、フィールドラベルに簡単にアクセスすることはできません。

フォームを受け入れるカスタムテンプレートタグを定義して、好みのレンダリングを生成することができます。これは、Pythonコードでは、フォームとフィールド名でフィールドラベルを取得するのが簡単だからです。または、ビュー内のラベルでエラーリストを作成し、それをコンテキストに追加して代わりに使用することもできます。

編集 代わりに、再び、あなたはフィールドを反復することができ、同様non_field_errorsを表示するために覚えて、個々のエラーを確認してください。次のようなものがあります。

<ul class="errorlist"> 
    {% if form.non_field_errors %} 
    <li>{{ form.non_field_errors }}</li> 
    {% endif %} 
    {% for field in form %} 
    {% if field.errors %} 
     <li> 
     {{ field.label }} 
     <ul class="errorlist"> 
      {% for error in field.errors %} 
      <li>{{ error }}</li> 
      {% endfor %} 
     </ul> 
     </li> 
    {% endif %} 
    {% endfor %} 
</ul> 

また、リストにnon_field_errorsをラップすることもできます。

+0

ありがとう、ピーター。私はErrorDictについて知らなかった。おそらく私はカスタムフィルターを使いました。 – broccoli2000

-1

これは、私がフィールドラベルを使ってエラーリストをレンダリングするために使用したフィルタです.Peterの提案に従います。

{% if form.errors %} 
    <ul class="user-msg error"> 
    {% for field in form %} 
     {% for error in field.errors %} 
      <li> 
       {% if field != '__all__' %} 
       <strong>{{ field.label }}:</strong> 
       {% endif %} 
       {{ error }} 
      </li> 
     {% endfor %} 
    {% endfor %} 
    </ul> 
{% endif %} 
+0

フィールドエラーがなければ、例外がスローされます。通常の完全なケースでは、 'form.errors'のキーが実際にフィールド名ではない可能性があります。コードを見ると、 'ErrorDict'の値は' errorList'のインスタンスです。これは 'error_li'メソッドとそれを取り囲む' ul'エレメントを構築できる 'as_ul'メソッドを持つクラスで、エスケープします有効になっていますので、 'error_li = errors.as_ul()'を実行してください。 –

9

すべてのフォームはdjango.forms.Formの代わりに継承されます。そこでは、form.errorsの方法が、ErrorDictas_ulメソッドがラベルを考慮に入れたカスタムを返すことによって変更されます。テンプレートを変更する必要はありませんが、フォームにCustomBaseFormを継承させる必要があります。

class CustomErrorDict(ErrorDict): 
    def __init__(self, form, iterable=None, **kwargs): 
     self.form = form 
     super(CustomErrorDict, self).__init__(iterable, **kwargs) 

    def as_ul(self): 
     if not self: 
      return u'' 

     def humanify(field_name): 
      try: 
       return self.form.fields[field_name].label or field_name 
      except: 
       return field_name 

     # main logic is copied from the original ErrorDict: 
     return mark_safe(u'<ul class="errorlist">%s</ul>' 
       % ''.join([u'<li>%s%s</li>' % (humanify(k), force_unicode(v)) 
        for k, v in self.items()])) 

class CustomBaseForm(forms.Form): 
    @property 
    def errors(self): 
     return CustomErrorDict(self, super(forms.Form, self).errors) 

    ... rest of CustomBaseForm ... 
+0

ありがとう、これは非常に役に立ちます。 –

+1

偉大な答えは、[django docs](https://docs.djangoproject.com/en/1.6/topics/forms/#looping-over-the-form-s-fields)もこれに関してかなり役に立ちます。 –

2

私はどのカスタムフォームクラスでこれを解決:私は、これはすでに私は同じシナリオ全体に走り、ラベルを使用する簡単な方法がある見つけ、回答されてきたが、知っている

from django.utils.safestring import mark_safe 
from django.template import Library, Context, loader 
register = Library() 

@register.filter 
def form_error_list(form): 

    result = ""  
    if form.errors: 
     fields = form.fields 
     error_items = [] 
     for error_field in form.errors: 
      label = fields[error_field].label 
      if not label: 
       label = ' '.join([word.capitalize() for word in error_field.split('_')]) 
      errors = form.errors[error_field] 
      error_li = ''.join(['<li>{0}</li>'.format(error) for error in errors]) 
      error_items.append({'label': label, 'error_li': error_li})  
     inner = ''.join(['<li>{0}<ul class="errorlist">{1}</ul></li>'.format(item['label'], item['error_li']) for item in error_items]) 
     result = mark_safe('<ul class="errorlist">{0}</ul>'.format(inner)) 

    return result 
2
from django import forms 

def my_clean(self): 
    self.my_errors = '' 
    for x in self.visible_fields(): 
     if x.errors: 
      self.my_errors += "<p>%s: %s</p>" % (x.label, x.errors) 


class SetPwdForm(forms.Form): 
    pwd= forms.CharField(label='password', required=True, min_length=6) 
    def clean(self): 
     ... 
     my_clean(self) 

myform.my_errorsビューでを使用しています。これは単なる基本的なテンプレートである、あなたはの世話をする必要があります

def form_invalid(self, form): 
    for field, errors in form.errors.items(): 
     for error in errors: 
      messages.error(
       self.request, 
       form.fields[field].label + ": " + error 
      ) 

注:

0

は、念のために誰もが、例えばでdjango.contrib.messagesフレームワークを使用して、このような何かをFormViewを探していますform.fields[field]が意味をなさない場合のコード内の非フィールドエラーなどが含まれます。

関連する問題