ホーム | HMDT3rd »

2006年5月24日

Djangoとnon-ascii文字列

djangoって、databaseから読み込んだデータはほぼ直接保持しようとするので、文字コー ドの変換とかしないんですね。

これだとnon-asciiを含む文字列をdatabaseから読み込んだときに、所期の動作をせず悲しいことになるので、ちょいと手を加えてみ ました。post-magic-removalで。

Index: django/db/models/base.py
===================================================================
--- django/db/models/base.py    (revision 2970)
+++ django/db/models/base.py    (working copy)
@@ -110,7 +110,8 @@
         if kwargs:
             raise TypeError, "'%s' is an invalid keyword argument for this function" % kwargs.keys()[0]
         for i, arg in enumerate(args):
-            setattr(self, self._meta.fields[i].attname, arg)
+            f = self._meta.fields[i]
+            setattr(self, f.attname, f.get_db_post_load(arg))
         dispatcher.send(signal=signals.post_init, sender=self.__class__, instance=self)

     def add_to_class(cls, name, value):
Index: django/db/models/fields/__init__.py
===================================================================
--- django/db/models/fields/__init__.py (revision 2970)
+++ django/db/models/fields/__init__.py (working copy)
@@ -156,6 +156,10 @@
         "Returns field's value just before saving."
         return value

+    def get_db_post_load(self, value):
+        "Returns field's value after loading from a database onto memory."
+        return value
+
     def get_db_prep_save(self, value):
         "Returns field's value prepared for saving into a database."
         return value
@@ -385,6 +389,34 @@
                 raise validators.ValidationError, gettext_lazy("This field cannot be null.")
         return str(value)

+# for handling of "utf-8" encoding (hironobu@nerv.or.jp,20060524)
+class UTF8StringField(CharField):
+    def get_manipulator_field_objs(self):
+        return [forms.TextField]
+
+    def get_internal_type(self):
+        return "CharField"
+
+    def get_db_post_load(self, value):
+        if value is not None:
+            value = value.decode('utf-8')
+        return Field.get_db_post_load(self, value)
+
+    def get_db_prep_lookup(self, lookup_type, value):
+        if value is not None:
+            value = value.decode('utf-8')
+        return Field.get_db_prep_lookup(self, lookup_type, value)
+
+    def to_python(self, value):
+        if isinstance(value, basestring):
+            return value.decode('utf-8')
+        if value is None:
+            if self.null:
+                return value
+            else:
+                raise validators.ValidationError, gettext_lazy("This field cannot be null.")
+        return value.decode('utf-8')
+
 # TODO: Maybe move this into contrib, because it's specialized.
 class CommaSeparatedIntegerField(CharField):
     def get_manipulator_field_objs(self):
contribあたりでもよかった気もするけど、まあ、それはそれで。

トラックバック(0)

トラックバックURL: http://foursics.jp/cgi-bin/mt/mt-tb.cgi/1

コメントする