perf: faster meta serialisation

This commit is contained in:
Sagar Vora 2025-06-21 20:12:39 +05:30
parent d9f1fc9aee
commit d9fc9f21f9

View file

@ -45,6 +45,9 @@ from frappe.utils import cached_property, cast, cint, cstr
from frappe.utils.caching import site_cache
from frappe.utils.data import add_to_date, get_datetime
ListOrTuple = list | tuple
SerializableTypes = str | int | float | datetime
DEFAULT_FIELD_LABELS = {
"name": _lt("ID"),
"creation": _lt("Created On"),
@ -176,31 +179,7 @@ class Meta(Document):
self.check_if_large_table()
def as_dict(self, no_nulls=False):
def serialize(doc):
if isinstance(doc, dict):
return doc.copy()
out = {}
for key, value in doc.__dict__.items():
if isinstance(value, list | tuple):
if not value or not isinstance(value[0], BaseDocument):
# non standard list object, skip
continue
value = [serialize(d) for d in value]
if (not no_nulls and value is None) or isinstance(
value, str | int | float | datetime | list | tuple
):
out[key] = value
# set empty lists for unset table fields
for fieldname in TABLE_DOCTYPES_FOR_DOCTYPE.keys():
if out.get(fieldname) is None:
out[fieldname] = []
return out
return serialize(self)
return _serialize(self, no_nulls=no_nulls)
def get_link_fields(self):
return self.get("fields", {"fieldtype": "Link", "options": ["!=", "[Select]"]})
@ -977,6 +956,28 @@ def _update_field_order_based_on_insert_after(field_order, insert_after_map):
field_order.extend(fields)
def _serialize(doc, no_nulls=False, *, is_child=False):
out = {}
for key, value in doc.__dict__.items():
if not is_child and isinstance(value, ListOrTuple):
if not value or not isinstance(value[0], BaseDocument):
# non standard list object, skip
continue
out[key] = [_serialize(d, no_nulls=no_nulls, is_child=True) for d in value]
elif (not no_nulls and value is None) or isinstance(value, SerializableTypes):
out[key] = value
# set empty lists for unset table fields
if not is_child:
for fieldname in TABLE_DOCTYPES_FOR_DOCTYPE:
if out.get(fieldname) is None:
out[fieldname] = []
return out
if typing.TYPE_CHECKING:
# This is DX hack to add all fields from DocType to meta for autocompletions.
# Meta is technically doctype + special fields on meta.