Development of an internal social media platform with personalised dashboards for students
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

hstore.py 1.7KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758
  1. import json
  2. from django import forms
  3. from django.core.exceptions import ValidationError
  4. from django.utils.translation import gettext_lazy as _
  5. __all__ = ['HStoreField']
  6. class HStoreField(forms.CharField):
  7. """
  8. A field for HStore data which accepts dictionary JSON input.
  9. """
  10. widget = forms.Textarea
  11. default_error_messages = {
  12. 'invalid_json': _('Could not load JSON data.'),
  13. 'invalid_format': _('Input must be a JSON dictionary.'),
  14. }
  15. def prepare_value(self, value):
  16. if isinstance(value, dict):
  17. return json.dumps(value)
  18. return value
  19. def to_python(self, value):
  20. if not value:
  21. return {}
  22. if not isinstance(value, dict):
  23. try:
  24. value = json.loads(value)
  25. except ValueError:
  26. raise ValidationError(
  27. self.error_messages['invalid_json'],
  28. code='invalid_json',
  29. )
  30. if not isinstance(value, dict):
  31. raise ValidationError(
  32. self.error_messages['invalid_format'],
  33. code='invalid_format',
  34. )
  35. # Cast everything to strings for ease.
  36. for key, val in value.items():
  37. if val is not None:
  38. val = str(val)
  39. value[key] = val
  40. return value
  41. def has_changed(self, initial, data):
  42. """
  43. Return True if data differs from initial.
  44. """
  45. # For purposes of seeing whether something has changed, None is
  46. # the same as an empty dict, if the data or initial value we get
  47. # is None, replace it w/ {}.
  48. initial_value = self.to_python(initial)
  49. return super().has_changed(initial_value, data)