fields.py 2.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071
  1. import json
  2. import six
  3. from django.core.exceptions import ValidationError
  4. from django.conf import settings
  5. from django.db import models
  6. from django.utils.encoding import force_text
  7. from social_core.utils import setting_name
  8. if getattr(settings, setting_name('POSTGRES_JSONFIELD'), False):
  9. from django.contrib.postgres.fields import JSONField as JSONFieldBase
  10. else:
  11. JSONFieldBase = models.TextField
  12. class JSONField(JSONFieldBase):
  13. """Simple JSON field that stores python structures as JSON strings
  14. on database.
  15. """
  16. def __init__(self, *args, **kwargs):
  17. kwargs.setdefault('default', dict)
  18. super(JSONField, self).__init__(*args, **kwargs)
  19. def from_db_value(self, value, *args, **kwargs):
  20. return self.to_python(value)
  21. def to_python(self, value):
  22. """
  23. Convert the input JSON value into python structures, raises
  24. django.core.exceptions.ValidationError if the data can't be converted.
  25. """
  26. if self.blank and not value:
  27. return {}
  28. value = value or '{}'
  29. if isinstance(value, six.binary_type):
  30. value = six.text_type(value, 'utf-8')
  31. if isinstance(value, six.string_types):
  32. try:
  33. return json.loads(value)
  34. except Exception as err:
  35. raise ValidationError(str(err))
  36. else:
  37. return value
  38. def validate(self, value, model_instance):
  39. """Check value is a valid JSON string, raise ValidationError on
  40. error."""
  41. if isinstance(value, six.string_types):
  42. super(JSONField, self).validate(value, model_instance)
  43. try:
  44. json.loads(value)
  45. except Exception as err:
  46. raise ValidationError(str(err))
  47. def get_prep_value(self, value):
  48. """Convert value to JSON string before save"""
  49. try:
  50. return json.dumps(value)
  51. except Exception as err:
  52. raise ValidationError(str(err))
  53. def value_to_string(self, obj):
  54. """Return value from object converted to string properly"""
  55. return force_text(self.value_from_object(obj))
  56. def value_from_object(self, obj):
  57. """Return value dumped to string."""
  58. orig_val = super(JSONField, self).value_from_object(obj)
  59. return self.get_prep_value(orig_val)