Skip to content

Instantly share code, notes, and snippets.

@ao5357
Created April 11, 2021 19:54
Show Gist options
  • Select an option

  • Save ao5357/18ddfe6a0d75f84b4c3391f2ee6eacbe to your computer and use it in GitHub Desktop.

Select an option

Save ao5357/18ddfe6a0d75f84b4c3391f2ee6eacbe to your computer and use it in GitHub Desktop.
Python prevent overriding serialization
class DataclassJSONEncoder(JSONEncoder):
""" JSON encoder for JSON mysql fields to handle encoding dataclasses and enum classes """
def default(self, o):
if is_dataclass(o):
return dataclasses.asdict(o)
elif isinstance(o, Enum):
return o.value
return super().default(o)
class DataclassJSONField(JSONField):
"""
Override to handle database level serialization/deserialization of dataclasses
- should be serialized from dataclass -> JSON
- should be deserialized from JSON -> dataclass
"""
def __init__(self, *args, **kwargs):
self.dataclass_cls = kwargs.pop("dataclass_cls", None)
kwargs["encoder"] = kwargs.pop("encoder", DataclassJSONEncoder(allow_nan=False))
super().__init__(*args, **kwargs)
def from_db_value(self, *args):
value = super().from_db_value(*args)
if value is None:
return None
# Note: this error checking would be better implemented in the __init__ method
# but we ran into issues with django migrations on existing fields placing it there.
if self.dataclass_cls is None:
raise NotImplementedError("No dataclass_cls set for DataclassJSONField")
return self.dataclass_cls(**value)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment