Created
April 11, 2021 19:54
-
-
Save ao5357/18ddfe6a0d75f84b4c3391f2ee6eacbe to your computer and use it in GitHub Desktop.
Python prevent overriding serialization
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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