Merge pull request #29196 from ankush/fix/meta_mutation
fix: Don't assume homogenous data in meta tables
This commit is contained in:
commit
c8ec528aa7
2 changed files with 53 additions and 32 deletions
|
|
@ -796,6 +796,16 @@ class TestDocType(IntegrationTestCase):
|
|||
)
|
||||
self.assertRaises(frappe.ValidationError, recursive_dt.insert)
|
||||
|
||||
def test_meta_serialization(self):
|
||||
doctype = new_doctype(
|
||||
fields=[{"fieldname": "some_fieldname", "fieldtype": "Data", "set_only_once": 1}],
|
||||
is_submittable=1,
|
||||
).insert()
|
||||
doc = frappe.new_doc(doctype.name, some_fieldname="something").insert()
|
||||
doc.save()
|
||||
doc.submit()
|
||||
frappe.get_meta(doctype.name).as_dict()
|
||||
|
||||
|
||||
def new_doctype(
|
||||
name: str | None = None,
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ import json
|
|||
import os
|
||||
import typing
|
||||
from datetime import datetime
|
||||
from functools import singledispatchmethod
|
||||
from functools import cached_property, singledispatchmethod
|
||||
from types import NoneType
|
||||
|
||||
import click
|
||||
|
|
@ -188,6 +188,8 @@ class Meta(Document):
|
|||
|
||||
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):
|
||||
|
|
@ -236,16 +238,19 @@ class Meta(Document):
|
|||
|
||||
def get_set_only_once_fields(self):
|
||||
"""Return fields with `set_only_once` set"""
|
||||
if not hasattr(self, "_set_only_once_fields"):
|
||||
self._set_only_once_fields = self.get("fields", {"set_only_once": 1})
|
||||
fieldnames = [d.fieldname for d in self._set_only_once_fields]
|
||||
|
||||
for df in self.standard_set_once_fields:
|
||||
if df.fieldname not in fieldnames:
|
||||
self._set_only_once_fields.append(df)
|
||||
|
||||
return self._set_only_once_fields
|
||||
|
||||
@cached_property
|
||||
def _set_only_once_fields(self):
|
||||
set_only_once_fields = self.get("fields", {"set_only_once": 1})
|
||||
fieldnames = [d.fieldname for d in set_only_once_fields]
|
||||
|
||||
for df in self.standard_set_once_fields:
|
||||
if df.fieldname not in fieldnames:
|
||||
set_only_once_fields.append(df)
|
||||
|
||||
return set_only_once_fields
|
||||
|
||||
def get_table_fields(self):
|
||||
return self._table_fields
|
||||
|
||||
|
|
@ -258,34 +263,40 @@ class Meta(Document):
|
|||
return fields
|
||||
|
||||
def get_valid_columns(self) -> list[str]:
|
||||
if not hasattr(self, "_valid_columns"):
|
||||
table_exists = frappe.db.table_exists(self.name)
|
||||
if self.name in self.special_doctypes and table_exists:
|
||||
self._valid_columns = get_table_columns(self.name)
|
||||
else:
|
||||
self._valid_columns = self.default_fields + [
|
||||
df.fieldname
|
||||
for df in self.get("fields")
|
||||
if not df.get("is_virtual") and df.fieldtype in data_fieldtypes
|
||||
]
|
||||
if self.istable:
|
||||
self._valid_columns += list(child_table_fields)
|
||||
|
||||
return self._valid_columns
|
||||
|
||||
def get_valid_fields(self) -> list[str]:
|
||||
if not hasattr(self, "_valid_fields"):
|
||||
if (frappe.flags.in_install or frappe.flags.in_migrate) and self.name in self.special_doctypes:
|
||||
self._valid_fields = get_table_columns(self.name)
|
||||
else:
|
||||
self._valid_fields = self.default_fields + [
|
||||
df.fieldname for df in self.get("fields") if df.fieldtype in data_fieldtypes
|
||||
]
|
||||
if self.istable:
|
||||
self._valid_fields += list(child_table_fields)
|
||||
@cached_property
|
||||
def _valid_columns(self):
|
||||
table_exists = frappe.db.table_exists(self.name)
|
||||
if self.name in self.special_doctypes and table_exists:
|
||||
valid_columns = get_table_columns(self.name)
|
||||
else:
|
||||
valid_columns = self.default_fields + [
|
||||
df.fieldname
|
||||
for df in self.get("fields")
|
||||
if not df.get("is_virtual") and df.fieldtype in data_fieldtypes
|
||||
]
|
||||
if self.istable:
|
||||
valid_columns += list(child_table_fields)
|
||||
|
||||
return valid_columns
|
||||
|
||||
def get_valid_fields(self) -> list[str]:
|
||||
return self._valid_fields
|
||||
|
||||
@cached_property
|
||||
def _valid_fields(self):
|
||||
if (frappe.flags.in_install or frappe.flags.in_migrate) and self.name in self.special_doctypes:
|
||||
valid_fields = get_table_columns(self.name)
|
||||
else:
|
||||
valid_fields = self.default_fields + [
|
||||
df.fieldname for df in self.get("fields") if df.fieldtype in data_fieldtypes
|
||||
]
|
||||
if self.istable:
|
||||
valid_fields += list(child_table_fields)
|
||||
|
||||
return valid_fields
|
||||
|
||||
def get_table_field_doctype(self, fieldname):
|
||||
return TABLE_DOCTYPES_FOR_DOCTYPE.get(fieldname)
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue