Home > Django > Django newformsのBooleanFieldで問題

Django newformsのBooleanFieldで問題

  • 2008-02-13 (水) 4:34
  • Django

newformでBooleanField関連のバグ(?)にあたった。
使っているのはsvn最新版のDjangoでバックエンドはMySQL5.0。

1.modelでBooloeanFieldを定義する
2.データベースにはtinyint型になる -> 0 or 1が入る
3.ModelFormを使ってフォーム作成
4.as_hiddenで出力 -> valueには0が設定される
5.そのままフォームで受け取ってバリデーション
6..データがTrueになってる!

Djangoのソースを見てみる。

newforms/forms.py 533行目から

PYTHON:
  1. class BooleanField(Field):
  2.     widget = CheckboxInput
  3.  
  4.     def clean(self, value):
  5.         """Returns a Python boolean object."""
  6.         super(BooleanField, self).clean(value)
  7.         # Explicitly check for the string 'False', which is what a hidden field
  8.         # will submit for False. Because bool("True") == True, we don't need to
  9.         # handle that explicitly.
  10.         if value == 'False':
  11.             return False
  12.         return bool(value)

bool(value)で0という「文字列」がTrueとなって返るみたい。
うーん。Falseって文字列だけチェックはまずくない?
"which is what a hidden field will submit for False"って、0か1が入ってるよ!

参考までに、db関連のコードがどうなっているか見てみた。

db/models/fields/__init__.py 445行目付近

PYTHON:
  1. class BooleanField(Field):
  2.     def __init__(self, *args, **kwargs):
  3.         kwargs['blank'] = True
  4.         Field.__init__(self, *args, **kwargs)
  5.  
  6.     def to_python(self, value):
  7.         if value in (True, False): return value
  8.         if value in ('t', 'True', '1'): return True
  9.         if value in ('f', 'False', '0'): return False
  10.         raise validators.ValidationError, _("This value must be either True or False.")

db/backends/utils.py 86行目

PYTHON:
  1. def typecast_boolean(s):
  2.     if s is None: return None
  3.     if not s: return False
  4.     return str(s)[0].lower() == 't'
  5.  
  6. 〜数行省略〜
  7.  
  8. def rev_typecast_boolean(obj, d):
  9.     return obj and '1' or '0'

二つのコードは違うけど、似たような処理をしている。
(typecast_booleanのほうは、文字列の0や1が入るのは想定していない様子。)
こんな感じの実装をnewformsのほうにも入れるべきなんだろうなー。
今回はカスタムフィールドを作る練習として、自分でMyBooleanFieldを定義して回避しといた。

関係ないけど、ModelFormはform_for_modelとかform_for_instanceに比べて自然な感じでいいと思う。

Comments:1

常山日記 08-02-14 (木) 3:32

[Django]巡回

Django Snippets: Comma separated users field django_template decorator Blog:…

Comment Form
Remember personal info

Trackbacks:0

Trackback URL for this entry
http://blog.joyfullife.jp/archives/2008/02/13043425.php/trackback
Listed below are links to weblogs that reference
Django newformsのBooleanFieldで問題 from 30からのBlog

Home > Django > Django newformsのBooleanFieldで問題

Search
Feeds
Meta

Return to page top