File: hstore.py

package info (click to toggle)
python-django 1.8.18-1~bpo8%2B1
  • links: PTS, VCS
  • area: main
  • in suites: jessie-backports
  • size: 41,628 kB
  • sloc: python: 189,488; xml: 695; makefile: 194; sh: 169; sql: 11
file content (47 lines) | stat: -rw-r--r-- 1,484 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
import json

from django import forms
from django.core.exceptions import ValidationError
from django.utils import six
from django.utils.translation import ugettext_lazy as _

__all__ = ['HStoreField']


class HStoreField(forms.CharField):
    """A field for HStore data which accepts JSON input."""
    widget = forms.Textarea
    default_error_messages = {
        'invalid_json': _('Could not load JSON data.'),
    }

    def prepare_value(self, value):
        if isinstance(value, dict):
            return json.dumps(value)
        return value

    def to_python(self, value):
        if not value:
            return {}
        if not isinstance(value, dict):
            try:
                value = json.loads(value)
            except ValueError:
                raise ValidationError(
                    self.error_messages['invalid_json'],
                    code='invalid_json',
                )
        # Cast everything to strings for ease.
        for key, val in value.items():
            value[key] = six.text_type(val)
        return value

    def has_changed(self, initial, data):
        """
        Return True if data differs from initial.
        """
        # For purposes of seeing whether something has changed, None is
        # the same as an empty dict, if the data or initial value we get
        # is None, replace it w/ {}.
        initial_value = self.to_python(initial)
        return super(HStoreField, self).has_changed(initial_value, data)