2012-04-20 19 views
1

高度な検索に使用するフォームがあります。フィールドの1つであるisland_groupはModelChoiceFieldであり、これはクエリーセットとしてvalues_listを戻しています(それぞれ異なる値を1回だけ取得するように)。DjangoはModelChoiceFieldにkeyerrorを作成します

forms.py:

class SearchForm(forms.Form): 
    ... 
    island_group = forms.ModelChoiceField(
     required=False, 
     queryset=Locality.objects.values_list('islandgroup', flat=True).distinct('islandgroup') 
    ... 

と私は値ではなく、オブジェクトを使用していますので、これはinvalid choiceの線に沿ってエラーがスローされますので、私はエラーをオーバーライドします。

def clean(self): 
     cleaned_data = super(SearchForm, self).clean() 

     if self._errors["island_group"]: 
      del self._errors["island_group"] 

     return cleaned_data 

しかし、私はKeyError at /collections/ 'island_group'エラーが発生し続ける。実際、このデータが読み取り専用のデータベースから取得されているので、私はちょっとした騒ぎでそれをビューに渡したいだけです。

ご協力いただければ幸いです。また、ここでのトレースバックがある:

Traceback: 
File "/home/sam/django-projects/datazone/local/lib/python2.7/site-packages/django/core/handlers/base.py" in get_response 
    111.       response = callback(request, *callback_args, **callback_kwargs) 
File "/home/sam/django-projects/datazone/bin/datazone/cdrs/views.py" in cdrs_index 
    59.  return render(request, 'cdrs_index.html', context)  
File "/home/sam/django-projects/datazone/local/lib/python2.7/site-packages/django/shortcuts/__init__.py" in render 
    44.  return HttpResponse(loader.render_to_string(*args, **kwargs), 
File "/home/sam/django-projects/datazone/local/lib/python2.7/site-packages/django/template/loader.py" in render_to_string 
    188.   return t.render(context_instance) 
File "/home/sam/django-projects/datazone/local/lib/python2.7/site-packages/django/template/base.py" in render 
    123.    return self._render(context) 
File "/home/sam/django-projects/datazone/local/lib/python2.7/site-packages/django/test/utils.py" in instrumented_test_render 
    57.  return self.nodelist.render(context) 
File "/home/sam/django-projects/datazone/local/lib/python2.7/site-packages/django/template/base.py" in render 
    744.     bits.append(self.render_node(node, context)) 
File "/home/sam/django-projects/datazone/local/lib/python2.7/site-packages/django/template/base.py" in render_node 
    757.   return node.render(context) 
File "/home/sam/django-projects/datazone/local/lib/python2.7/site-packages/django/template/loader_tags.py" in render 
    127.   return compiled_parent._render(context) 
File "/home/sam/django-projects/datazone/local/lib/python2.7/site-packages/django/test/utils.py" in instrumented_test_render 
    57.  return self.nodelist.render(context) 
File "/home/sam/django-projects/datazone/local/lib/python2.7/site-packages/django/template/base.py" in render 
    744.     bits.append(self.render_node(node, context)) 
File "/home/sam/django-projects/datazone/local/lib/python2.7/site-packages/django/template/base.py" in render_node 
    757.   return node.render(context) 
File "/home/sam/django-projects/datazone/local/lib/python2.7/site-packages/django/template/loader_tags.py" in render 
    64.    result = block.nodelist.render(context) 
File "/home/sam/django-projects/datazone/local/lib/python2.7/site-packages/django/template/base.py" in render 
    744.     bits.append(self.render_node(node, context)) 
File "/home/sam/django-projects/datazone/local/lib/python2.7/site-packages/django/template/base.py" in render_node 
    757.   return node.render(context) 
File "/home/sam/django-projects/datazone/local/lib/python2.7/site-packages/django/template/defaulttags.py" in render 
    227.     nodelist.append(node.render(context)) 
File "/home/sam/django-projects/datazone/local/lib/python2.7/site-packages/django/template/base.py" in render 
    792.    output = self.filter_expression.resolve(context) 
File "/home/sam/django-projects/datazone/local/lib/python2.7/site-packages/django/template/base.py" in resolve 
    510.     obj = self.var.resolve(context) 
File "/home/sam/django-projects/datazone/local/lib/python2.7/site-packages/django/template/base.py" in resolve 
    653.    value = self._resolve_lookup(context) 
File "/home/sam/django-projects/datazone/local/lib/python2.7/site-packages/django/template/base.py" in _resolve_lookup 
    683.       current = getattr(current, bit) 
File "/home/sam/django-projects/datazone/local/lib/python2.7/site-packages/django/forms/forms.py" in _errors 
    415.   return self.form.errors.get(self.name, self.form.error_class()) 
File "/home/sam/django-projects/datazone/local/lib/python2.7/site-packages/django/forms/forms.py" in _get_errors 
    112.    self.full_clean() 
File "/home/sam/django-projects/datazone/local/lib/python2.7/site-packages/django/forms/forms.py" in full_clean 
    268.   self._clean_form() 
File "/home/sam/django-projects/datazone/local/lib/python2.7/site-packages/django/forms/forms.py" in _clean_form 
    296.    self.cleaned_data = self.clean() 
File "/home/sam/django-projects/datazone/bin/datazone/cdrs/forms.py" in clean 
    113.   if self._errors["island_group"]: 

Exception Type: KeyError at /collections/ 
Exception Value: 'island_group' 

答えて

0

更新

私は私があなたの例外を知っていると思う、それはSelect a valid choice. That choice is not one of the available choices.右のように見えるかもしれませんか? あなたがqueryset=に渡したLocality.objects.values_list('islandgroup', flat=True).distinct('islandgroup')は、QuerySetの代わりにValuesListQuerySetです。 ValueListQuerySetインスタンスには_meta情報が含まれておらず、通常のリストとして使用されているため、ModelChoiceFieldに間違ったフォームオプションが生成されます。ただ、

>>> from django import forms 
>>> from django.contrib.auth.models import * 

>>> class F(forms.Form): 
...  user = forms.ModelChoiceForm(queryset=User.objects.values_list('username', flat=True)) 

>>> print F().as_p() 
<p><label for="id_user">User:</label> <select name="user" id="id_user"> 
<option value="" selected="selected">---------</option> 
<option value="okm">okm</option> 
</select></p> 

以下の不自然な例のようにしかし、第2のオプションの正しい値は、このようにあなたのコードでisland_group =行を変更する必要があるだけで

>>> class F(forms.Form): 
...  user = forms.ModelChoiceForm(queryset=User.objects) 

>>> print F().as_p() 
<p><label for="id_user">User:</label> <select name="user" id="id_user"> 
<option value="" selected="selected">---------</option> 
<option value="1">okm</option> 
</select></p> 

のように、ユーザーOKMのpkする必要がありますislandgroupモデルフィールドのタイプに応じて異なります。

上記の問題を除いて、コードは問題ありません。したがって、他の'island_group'検証エラーがself._errorsにない場合、self._errors["island_group"]はKeyErrorを発生させます。

+0

カスタムクリーンメソッドを削除すると、無効な選択エラーが表示されます。フィールドで何も選択されていない場合、フィールドはバリデーションを行い、何かを選択すると直ちにエラーが発生します。私はこれは文字列の値でオブジェクトではないからだと思います。だから、基本的に私はDjangoがオブジェクトではないので私の失敗を止めるために必要なだけで、カスタムクリーンメソッドは私が思い付いた最高でした。私はあなたの3番目の段落を理解しているとは思えません。なぜ、 'self._errors [" island_group "]' KeyErrorを引き起こしているのかをチェックしていますか? –

+0

@DarwinTech 'KeyError'は、' {} ['key'] 'で例外が発生したのと同じように、Python例外です。 {} {{key}] ' – okm

+0

で{'} .get(' key ')'または' {key} 'の場合はそれを避けることができます。これは、カスタムクリーンメソッドで動作します:self._errorsの '' island_group '':del self._errors ["island_group"] '。 'invalid choice'検証エラーのstacktraceを投稿したいと思います - Djangoが失敗しないときにアクセスするにはどうしたらいいですか? –

関連する問題