Matthew Schinckel avatar Matthew Schinckel committed f3dc09c

Better handle blank and null field attributes.
Resolves #13.
Includes tests based on inactivist.

Comments (0)

Files changed (3)


     __metaclass__ = models.SubfieldBase
     default_error_messages = {
-        'invalid': _(u"Enter a valid JSON string.")
+        'invalid': _(u"'%s' is not a valid JSON string.")
     description = "JSON object"
     def to_python(self, value):
         if isinstance(value, basestring):
+            if value is None:
+                return None
             if value == "":
-                return None
-            value = json.loads(value)
+                if self.null:
+                    return None
+                if self.blank:
+                    return ""
+            try:
+                value = json.loads(value)
+            except ValueError:
+                msg = self.error_messages['invalid'] % str(value)
+                raise ValidationError(msg)
         # TODO: Look for date/time/datetime objects within the structure?
         return value
     def get_db_prep_value(self, value, connection=None, prepared=None):
         if value is None:
+            if not self.null and self.blank:
+                return ""
             return None
         return json.dumps(value, default=default)


 from django.test import TestCase as DjangoTestCase
 from django.utils import unittest
-from jsonfield.tests.jsonfield_test_app.models import (
-    JSONFieldTestModel,
-    JSONFieldWithDefaultTestModel,
+from jsonfield.tests.jsonfield_test_app.models import *
 from jsonfield import JSONField
 class JSONFieldTest(DjangoTestCase):
         self.assertEquals(1, JSONFieldTestModel.objects.filter(json=None).count())
-        self.assertEquals(None, JSONFieldTestModel.objects.get(json=None).json)
+        self.assertEquals(None, JSONFieldTestModel.objects.get(json=None).json)
+    def test_jsonfield_blank(self):
+        BlankJSONFieldTestModel.objects.create(blank_json='', null_json=None)
+        obj = BlankJSONFieldTestModel.objects.get()
+        self.assertEquals(None, obj.null_json)
+        self.assertEquals("", obj.blank_json)
+        obj = BlankJSONFieldTestModel.objects.get()
+        self.assertEquals(None, obj.null_json)
+        self.assertEquals("", obj.blank_json)


     class Meta:
         app_label = 'jsonfield'
+class BlankJSONFieldTestModel(models.Model):
+    null_json = JSONField(null=True)
+    blank_json = JSONField(blank=True)
+    class Meta:
+        app_label = 'jsonfield'
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.