perf: optimize expand link for table fields

This commit is contained in:
Sumit Bhanushali 2025-10-27 13:00:43 +05:30
parent 4cfc0c6b55
commit f5fed5b4be
3 changed files with 49 additions and 45 deletions

View file

@ -4,6 +4,7 @@ from werkzeug.routing import Rule
import frappe
from frappe import _
from frappe.utils import attach_expanded_links
from frappe.utils.data import sbool
@ -104,11 +105,8 @@ def get_values_for_table_and_multiselect_fields(doc_dict):
table_fields = meta.get_table_fields()
for field in table_fields:
if not doc_dict.get(field.fieldname):
continue
for value in doc_dict.get(field.fieldname):
value.update(get_values_for_link_and_dynamic_link_fields(value))
table_link_fieldnames = [f.fieldname for f in frappe.get_meta(field.options).get_link_fields()]
attach_expanded_links(field.options, doc_dict.get(field.fieldname), table_link_fieldnames)
def execute_doc_method(doctype: str, name: str, method: str | None = None):

View file

@ -2,7 +2,6 @@
# License: MIT. See LICENSE
import json
import os
from collections import defaultdict
from typing import TYPE_CHECKING
import frappe
@ -12,7 +11,7 @@ from frappe import _
from frappe.desk.reportview import validate_args
from frappe.model.db_query import check_parent_permission
from frappe.model.utils import is_virtual_doctype
from frappe.utils import get_safe_filters
from frappe.utils import attach_expanded_links, get_safe_filters
from frappe.utils.caching import http_cache
if TYPE_CHECKING:
@ -74,44 +73,7 @@ def get_list(
if fields and not fields[0] == "*":
expand = [f for f in expand if f in fields]
meta = frappe.get_meta(doctype)
link_fields = {f.fieldname: f for f in meta.get_link_fields() + meta.get_dynamic_link_fields()}
doctype_values = defaultdict(set)
field_to_doctype = {}
for fieldname in expand:
if fieldname not in link_fields:
continue
e = link_fields[fieldname]
link_doctype = e.options
field_to_doctype[fieldname] = link_doctype
for li in _list:
val = li.get(fieldname)
if val:
doctype_values[link_doctype].add(val)
doctype_title_maps = {}
for link_doctype, values in doctype_values.items():
records = frappe.get_all(
link_doctype,
filters={"name": ["in", list(values)]},
fields=["*"],
)
doctype_title_maps[link_doctype] = {r["name"]: r for r in records}
for li in _list:
for fieldname in expand:
if fieldname not in field_to_doctype:
continue
link_doctype = field_to_doctype[fieldname]
val = li.get(fieldname)
val_title = doctype_title_maps.get(link_doctype, {}).get(val)
if val and val_title:
li[fieldname] = val_title
attach_expanded_links(doctype, _list, expand)
return _list

View file

@ -2776,3 +2776,47 @@ def map_trackers(url_trackers: dict, create: bool = False):
frappe_trackers["utm_content"] = url_content
return frappe_trackers
def attach_expanded_links(doctype: str, docs: list, fields_to_expand: list):
if not fields_to_expand:
return
meta = frappe.get_meta(doctype)
link_fields = {f.fieldname: f for f in meta.get_link_fields() + meta.get_dynamic_link_fields()}
doctype_values = defaultdict(set)
field_to_doctype = {}
for fieldname in fields_to_expand:
if fieldname not in link_fields:
continue
e = link_fields[fieldname]
link_doctype = e.options
field_to_doctype[fieldname] = link_doctype
for li in docs:
val = li.get(fieldname)
if val:
doctype_values[link_doctype].add(val)
doctype_title_maps = {}
for link_doctype, values in doctype_values.items():
records = frappe.get_all(
link_doctype,
filters={"name": ["in", list(values)]},
fields=["*"],
)
doctype_title_maps[link_doctype] = {r["name"]: r for r in records}
for li in docs:
for fieldname in fields_to_expand:
if fieldname not in field_to_doctype:
continue
link_doctype = field_to_doctype[fieldname]
val = li.get(fieldname)
val_title = doctype_title_maps.get(link_doctype, {}).get(val)
if val and val_title:
li[fieldname] = val_title