From a14e890c92a7c502699f7627ec1d001b322deeb5 Mon Sep 17 00:00:00 2001 From: Dominik George <dominik.george@teckids.org> Date: Mon, 16 Nov 2020 00:49:49 +0100 Subject: [PATCH] Ensure reverse related fields are saved after using syncable fields proxies --- aleksis/core/mixins.py | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/aleksis/core/mixins.py b/aleksis/core/mixins.py index 1b82388a8..9af019050 100644 --- a/aleksis/core/mixins.py +++ b/aleksis/core/mixins.py @@ -48,7 +48,7 @@ class _ExtensibleModelBase(models.base.ModelBase): return mcls -def _generate_proxy_property(field, subfield): +def _generate_one_to_one_proxy_property(field, subfield): def getter(self): if hasattr(self, field.name): related = getattr(self, field.name) @@ -63,6 +63,8 @@ def _generate_proxy_property(field, subfield): # Auto-create related instance (but do not save) related = field.related_model() setattr(related, field.remote_field.name, self) + # Ensure the related model is saved later + self._save_reverse = getattr(self, "_save_reverse", []) + [related] setattr(related, subfield.name, val) return property(getter, setter) @@ -317,7 +319,7 @@ class ExtensibleModel(models.Model, metaclass=_ExtensibleModelBase): if not hasattr(cls, name): # Add proxy properties to handle access to related model - setattr(cls, name, _generate_proxy_property(field, subfield)) + setattr(cls, name, _generate_one_to_one_proxy_property(field, subfield)) # Generate a fake field class with enough API to detect attribute names fields.append( @@ -349,6 +351,16 @@ class ExtensibleModel(models.Model, metaclass=_ExtensibleModelBase): """Dynamically add a new permission to a model.""" cls.extra_permissions.append((name, verbose_name)) + def save(self, *args, **kwargs): + """Ensure all functionality of our extensions that needs saving gets it.""" + # For auto-created remote syncable fields + if hasattr(self, "_save_reverse"): + for related in self._save_reverse: + related.save() + del self._save_reverse + + super().save(*args, **kwargs) + class Meta: abstract = True -- GitLab