From b9b280a4a62f35f00b008f0066561dfe263ed87a Mon Sep 17 00:00:00 2001 From: Dominik George <dominik.george@teckids.org> Date: Mon, 16 Nov 2020 00:18:23 +0100 Subject: [PATCH] Factor out proxy attribute generation to separate function Closures are hard! --- aleksis/core/mixins.py | 38 +++++++++++++++++++++----------------- 1 file changed, 21 insertions(+), 17 deletions(-) diff --git a/aleksis/core/mixins.py b/aleksis/core/mixins.py index 230379ee0..1b82388a8 100644 --- a/aleksis/core/mixins.py +++ b/aleksis/core/mixins.py @@ -48,6 +48,26 @@ class _ExtensibleModelBase(models.base.ModelBase): return mcls +def _generate_proxy_property(field, subfield): + def getter(self): + if hasattr(self, field.name): + related = getattr(self, field.name) + return getattr(related, subfield.name) + # Related instane does not exist + return None + + def setter(self, val): + if hasattr(self, field.name): + related = getattr(self, field.name) + else: + # Auto-create related instance (but do not save) + related = field.related_model() + setattr(related, field.remote_field.name, self) + setattr(related, subfield.name, val) + + return property(getter, setter) + + class ExtensibleModel(models.Model, metaclass=_ExtensibleModelBase): """Base model for all objects in AlekSIS apps. @@ -297,23 +317,7 @@ class ExtensibleModel(models.Model, metaclass=_ExtensibleModelBase): if not hasattr(cls, name): # Add proxy properties to handle access to related model - def getter(self): - if hasattr(self, field.name): - related = getattr(self, field.name) - return getattr(related, subfield.name) - # Related instane does not exist - return None - - def setter(self, val): - if hasattr(self, field.name): - related = getattr(self, field.name) - else: - # Auto-create related instance (but do not save) - related = field.related_model() - setattr(related, field.remote_field.name, self) - setattr(related, subfield.name, val) - - setattr(cls, name, property(getter, setter)) + setattr(cls, name, _generate_proxy_property(field, subfield)) # Generate a fake field class with enough API to detect attribute names fields.append( -- GitLab