Skip to content

Commit ffc2b0c

Browse files
Added option to restrict the form field and fixed how empty objects are handled.
1 parent 2574c49 commit ffc2b0c

File tree

5 files changed

+26
-12
lines changed

5 files changed

+26
-12
lines changed

README.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@ Add a ``JSONField`` to your model like any other field.
6565
- ``decoder``: Custom JSON decoder (default: ``json_field.fields.JSONDecoder``)
6666
- ``encoder_kwargs``: Specify all arguments to the encoder (overrides ``encoder``)
6767
- ``decoder_kwargs``: Specify all arguments to the decoder (overrides ``decoder``)
68+
- ``simple_formfield``: Restrict use of the ``datetime`` and ``Decimal`` objects in the form field
6869

6970
License
7071
-------

json_field/fields.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@ def __init__(self, *args, **kwargs):
6868
'invalid': _(u'Enter a valid JSON object')
6969
}
7070
self._db_type = kwargs.pop('db_type', None)
71+
self.simple_formfield = kwargs.pop('simple_formfield', False)
7172

7273
encoder = kwargs.pop('encoder', DjangoJSONEncoder)
7374
decoder = kwargs.pop('decoder', JSONDecoder)
@@ -91,7 +92,7 @@ def db_type(self, connection):
9192
return super(JSONField, self).db_type(connection)
9293

9394
def to_python(self, value):
94-
if not value:
95+
if value is None: # allow blank objects
9596
return None
9697
if isinstance(value, basestring):
9798
try:
@@ -114,6 +115,7 @@ def value_from_object(self, obj):
114115
def formfield(self, **kwargs):
115116
defaults = {
116117
'form_class': kwargs.get('form_class', JSONFormField),
118+
'simple': self.simple_formfield,
117119
'encoder_kwargs': self.encoder_kwargs,
118120
'decoder_kwargs': self.decoder_kwargs,
119121
}

json_field/forms.py

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
class JSONFormField(fields.Field):
88

99
def __init__(self, *args, **kwargs):
10+
self.simple = kwargs.pop('simple', False)
1011
self.encoder_kwargs = kwargs.pop('encoder_kwargs')
1112
self.decoder_kwargs = kwargs.pop('decoder_kwargs')
1213
super(JSONFormField, self).__init__(*args, **kwargs)
@@ -21,15 +22,25 @@ def clean(self, value):
2122

2223
json_globals = { # safety first!
2324
'__builtins__': None,
24-
'datetime': datetime,
25-
'Decimal': decimal.Decimal,
25+
}
26+
if not self.simple: # optional restriction
27+
json_globals.update({
28+
'datetime': datetime,
29+
'Decimal': decimal.Decimal,
30+
})
31+
json_locals = { # value compatibility
32+
'null': None,
33+
'true': True,
34+
'false': False,
2635
}
2736
try:
28-
value = json.dumps(eval(value, json_globals, {}), **self.encoder_kwargs)
37+
value = json.dumps(eval(value, json_globals, json_locals), **self.encoder_kwargs)
2938
except Exception, e: # eval can throw many different errors
3039
raise util.ValidationError('%s (Caught "%s")' % (self.help_text, e))
40+
3141
try:
3242
json.loads(value, **self.decoder_kwargs)
3343
except ValueError, e:
3444
raise util.ValidationError('%s (Caught "%s")' % (self.help_text, e))
45+
3546
return value

test_project/app/models.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,4 +5,4 @@
55
class Test(models.Model):
66

77
json = JSONField()
8-
json_null = JSONField(blank=True, null=True)
8+
json_null = JSONField(blank=True, null=True, simple_formfield=True)

test_project/app/tests.py

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -28,14 +28,14 @@ def test_null(self):
2828
self.assertEqual(None, t1.json)
2929
self.assertEqual('null', t1.get_json_json())
3030
t2 = Test.objects.create(json='')
31-
self.assertEqual(None, t2.json)
32-
self.assertEqual('null', t2.get_json_json())
31+
self.assertEqual('', t2.json)
32+
self.assertEqual('""', t2.get_json_json())
3333
t3 = Test.objects.create(json_null=None)
3434
self.assertEqual(None, t3.json_null)
3535
self.assertEqual('null', t3.get_json_null_json())
3636
t4 = Test.objects.create(json_null='')
37-
self.assertEqual(None, t4.json_null)
38-
self.assertEqual('null', t4.get_json_null_json())
37+
self.assertEqual('', t4.json_null)
38+
self.assertEqual('""', t4.get_json_null_json())
3939

4040
def test_decimal(self):
4141
t1 = Test.objects.create(json=Decimal(1.24))
@@ -72,9 +72,9 @@ def test_get_set_json(self):
7272
t1 = Test.objects.create(json={'test':123})
7373
self.assertEqual({'test':123}, t1.json)
7474
self.assertEqual('{"test": 123}', t1.get_json_json())
75-
t2 = Test.objects.create()
76-
self.assertEqual(None, t2.json)
77-
self.assertEqual('null', t2.get_json_json())
75+
t2 = Test.objects.create(json='')
76+
self.assertEqual('', t2.json)
77+
self.assertEqual('""', t2.get_json_json())
7878
self.assertEqual(None, t2.json_null)
7979
self.assertEqual('null', t2.get_json_null_json())
8080
t3 = Test.objects.create(json=[1,2,3])

0 commit comments

Comments
 (0)