OpenSlides/openslides/utils/jsonfield/fields.py

78 lines
2.3 KiB
Python

from django.db import models
from django.core.serializers.json import DjangoJSONEncoder
from django.utils import simplejson as json
from django.utils.translation import ugettext_lazy as _
from django.forms.fields import Field
from django.forms.util import ValidationError as FormValidationError
class JSONFormField(Field):
def clean(self, value):
if not value and not self.required:
return None
value = super(JSONFormField, self).clean(value)
if isinstance(value, basestring):
try:
json.loads(value)
except ValueError:
raise FormValidationError(_("Enter valid JSON"))
return value
class JSONField(models.TextField):
"""JSONField is a generic textfield that serializes/unserializes JSON objects"""
# Used so to_python() is called
__metaclass__ = models.SubfieldBase
def __init__(self, *args, **kwargs):
self.dump_kwargs = kwargs.pop('dump_kwargs', {'cls': DjangoJSONEncoder})
self.load_kwargs = kwargs.pop('load_kwargs', {})
super(JSONField, self).__init__(*args, **kwargs)
def to_python(self, value):
"""Convert string value to JSON"""
if isinstance(value, basestring):
try:
return json.loads(value, **self.load_kwargs)
except ValueError:
pass
return value
def get_db_prep_value(self, value, connection, prepared=False):
"""Convert JSON object to a string"""
if isinstance(value, basestring):
return value
return json.dumps(value, **self.dump_kwargs)
def value_to_string(self, obj):
value = self._get_val_from_obj(obj)
return self.get_prep_value(value)
def value_from_object(self, obj):
return json.dumps(super(JSONField, self).value_from_object(obj))
def formfield(self, **kwargs):
if "form_class" not in kwargs:
kwargs["form_class"] = JSONFormField
field = super(JSONField, self).formfield(**kwargs)
if not field.help_text:
field.help_text = "Enter valid JSON"
return field
try:
from south.modelsinspector import add_introspection_rules
add_introspection_rules([], ["^jsonfield\.fields\.JSONField"])
except ImportError:
pass