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