diff --git a/frappe/database/database.py b/frappe/database/database.py index 39c7490b83..70345a04dd 100644 --- a/frappe/database/database.py +++ b/frappe/database/database.py @@ -550,7 +550,7 @@ class Database(object): return r and [[i[1] for i in r]] or [] - def get_singles_dict(self, doctype, debug = False): + def get_singles_dict(self, doctype, debug=False, *, for_update=False): """Get Single DocType as dict. :param doctype: DocType of the single object whose value is requested @@ -561,10 +561,13 @@ class Database(object): account_settings = frappe.db.get_singles_dict("Accounts Settings") """ result = self.query.get_sql( - "Singles", filters={"doctype": doctype}, fields=["field", "value"] + "Singles", + filters={"doctype": doctype}, + fields=["field", "value"], + for_update=for_update, ).run() - dict_ = frappe._dict(result) - return dict_ + + return frappe._dict(result) @staticmethod def get_all(*args, **kwargs): diff --git a/frappe/model/document.py b/frappe/model/document.py index 053f0350fe..15e9c28d83 100644 --- a/frappe/model/document.py +++ b/frappe/model/document.py @@ -88,35 +88,27 @@ class Document(BaseDocument): If DocType name and document name are passed, the object will load all values (including child documents) from the database. """ - self.doctype = self.name = None - self._default_new_docs = {} + self.doctype = None + self.name = None self.flags = frappe._dict() - if args and args[0] and isinstance(args[0], str): - # first arugment is doctype - if len(args)==1: - # single - self.doctype = self.name = args[0] - else: + if args and args[0]: + if isinstance(args[0], str): + # first arugment is doctype self.doctype = args[0] - if isinstance(args[1], dict): - # filter - self.name = frappe.db.get_value(args[0], args[1], "name") - if self.name is None: - frappe.throw(_("{0} {1} not found").format(_(args[0]), args[1]), - frappe.DoesNotExistError) - else: - self.name = args[1] - if 'for_update' in kwargs: - self.flags.for_update = kwargs.get('for_update') + # doctype for singles, string value or filters for other documents + self.name = self.doctype if len(args) == 1 else args[1] - self.load_from_db() - return + # for_update is set in flags to avoid changing load_from_db signature + # since it is used in virtual doctypes and inherited in child classes + self.flags.for_update = kwargs.get("for_update") + self.load_from_db() + return - if args and args[0] and isinstance(args[0], dict): - # first argument is a dict - kwargs = args[0] + if isinstance(args[0], dict): + # first argument is a dict + kwargs = args[0] if kwargs: # init base document @@ -133,17 +125,15 @@ class Document(BaseDocument): frappe.whitelist()(fn) return fn - def reload(self): - """Reload document from database""" - self.load_from_db() - def load_from_db(self): """Load document and children from database and create properties from fields""" if not getattr(self, "_metaclass", False) and self.meta.issingle: - single_doc = frappe.db.get_singles_dict(self.doctype) + single_doc = frappe.db.get_singles_dict( + self.doctype, for_update=self.flags.for_update + ) if not single_doc: - single_doc = frappe.new_doc(self.doctype).as_dict() + single_doc = frappe.new_doc(self.doctype, as_dict=True) single_doc["name"] = self.doctype del single_doc["__islocal"] @@ -177,6 +167,8 @@ class Document(BaseDocument): if hasattr(self, "__setup__"): self.__setup__() + reload = load_from_db + def get_latest(self): if not getattr(self, "latest", None): self.latest = frappe.get_doc(self.doctype, self.name)