a field for hstore data which accepts dictionary json input cast everything to strings for ease 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 a field for hstore data which accepts dictionary json input cast everything to strings for ease 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
import json

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

__all__ = ["HStoreField"]


class HStoreField(forms.CharField):
    

    widget = forms.Textarea
    default_error_messages = {
        "invalid_json": _("Could not load JSON data."),
        "invalid_format": _("Input must be a JSON dictionary."),
    }

    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 json.JSONDecodeError:
                raise ValidationError(
                    self.error_messages["invalid_json"],
                    code="invalid_json",
                )

        if not isinstance(value, dict):
            raise ValidationError(
                self.error_messages["invalid_format"],
                code="invalid_format",
            )

        
        for key, val in value.items():
            if val is not None:
                val = str(val)
            value[key] = val
        return value

    def has_changed(self, initial, data):
        
        
        
        
        initial_value = self.to_python(initial)
        return super().has_changed(initial_value, data)