perf: faster meta serialisation
This commit is contained in:
parent
d9f1fc9aee
commit
d9fc9f21f9
1 changed files with 26 additions and 25 deletions
|
|
@ -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.
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue