From f0b92bb475b04444008eb172841ce88ca071896a Mon Sep 17 00:00:00 2001 From: Egor fureunoir Gorbunov Date: Mon, 9 Mar 2026 16:44:21 +0300 Subject: [PATCH] feat(fields): migrate from json to orjson for improved performance migrate field serialization/deserialization to use `orjson` instead of `json` for better performance and ensure compatibility with decryption using `cryptography.fernet`. Handle potential invalid tokens and decoding errors gracefully. --- schon/fields.py | 23 +++++++++++++++++------ 1 file changed, 17 insertions(+), 6 deletions(-) diff --git a/schon/fields.py b/schon/fields.py index 8e5dc8d5..33dfa3cd 100644 --- a/schon/fields.py +++ b/schon/fields.py @@ -1,5 +1,5 @@ -import json - +import orjson +from cryptography.fernet import InvalidToken from encrypted_fields.fields import EncryptedTextField @@ -18,16 +18,20 @@ class EncryptedJSONTextField(EncryptedTextField): def get_prep_value(self, value): if value is not None and not isinstance(value, str): - value = json.dumps(value, default=str) + value = orjson.dumps(value, default=str).decode("utf-8") return super().get_prep_value(value) def from_db_value(self, value, expression, connection): - value = super().from_db_value(value, expression, connection) if value is None: return None if isinstance(value, str): try: - return json.loads(value) + value = self.f.decrypt(value.encode("utf-8")).decode("utf-8") + except (InvalidToken, UnicodeEncodeError): + pass + if isinstance(value, str): + try: + return orjson.loads(value) except (ValueError, TypeError): pass return value @@ -35,9 +39,16 @@ class EncryptedJSONTextField(EncryptedTextField): def to_python(self, value): if isinstance(value, (dict, list)): return value + if value is None: + return value if isinstance(value, str): + if not hasattr(self, "_already_decrypted"): + try: + value = self.f.decrypt(value.encode("utf-8")).decode("utf-8") + except (InvalidToken, UnicodeEncodeError): + pass try: - return json.loads(value) + return orjson.loads(value) except (ValueError, TypeError): pass return value