Commits

offline committed aa0dea0

JSONField added

Comments (0)

Files changed (1)

annoying/fields.py

+from django.db import models
 from django.db.models import OneToOneField
+from django.utils import simplejson as json
+from django.core.serializers.json import DjangoJSONEncoder
 from django.db.models.fields.related import SingleRelatedObjectDescriptor
 
 
             obj.save()
             return obj
 
+
 class AutoOneToOneField(OneToOneField):
     '''
     OneToOneField creates related object on first call if it doesnt exists yet.
         
         class MyProfile(models.Model):
             user = AutoOneToOneField(User, primary_key=True)
-            home_page = models.URLField(max_length=255)
-            icq = models.CharField(max_length=255)
+            home_page = models.URLField(max_length=255, blank=True)
+            icq = models.IntegerField(max_length=255, null=True)
     '''
     def contribute_to_related_class(self, cls, related):
         setattr(cls, related.get_accessor_name(), AutoSingleRelatedObjectDescriptor(related))
 
+
+class JSONField(models.TextField):
+    """
+    JSONField is a generic textfield that neatly serializes/unserializes
+    JSON objects seamlessly.
+    Django snippet #1478
+
+    example:
+        class Page(models.Model):
+            data = JSONField(blank=True, null=True)
+
+
+        page = Page.objects.get(pk=5)
+        page.data = {'title': 'test', 'type': 3}
+        page.save()
+    """
+
+    __metaclass__ = models.SubfieldBase
+
+    def to_python(self, value):
+        if value == "":
+            return None
+
+        try:
+            if isinstance(value, basestring):
+                return json.loads(value)
+        except ValueError:
+            pass
+        return value
+
+    def get_db_prep_save(self, value):
+        if value == "":
+            return None
+        if isinstance(value, dict):
+            value = json.dumps(value, cls=DjangoJSONEncoder)
+        return super(JSONField, self).get_db_prep_save(value)
+