From 303c8f332239dd705221930eeb76d57ecb18a4ca Mon Sep 17 00:00:00 2001
From: Dominik George <dominik.george@teckids.org>
Date: Wed, 5 Jul 2023 21:05:31 +0200
Subject: [PATCH] Correctly add fields in ExtensibleFOrms if not all fields are
 used

---
 CHANGELOG.rst          |  1 +
 aleksis/core/mixins.py | 16 +++++++++++++++-
 2 files changed, 16 insertions(+), 1 deletion(-)

diff --git a/CHANGELOG.rst b/CHANGELOG.rst
index 02efc9e95..c6a799938 100644
--- a/CHANGELOG.rst
+++ b/CHANGELOG.rst
@@ -18,6 +18,7 @@ Fixed
 * When navigating from legacy to legacy page, the latter would reload once for no reason.
 * The oauth authorization page was not accessible when the service worker was active.
 * [Docker] Clear obsolete bundle parts when adding apps using ONBUILD
+* Extensible forms that used a subset of fields did not render properly
 
 `3.1.1`_ - 2023-07-01
 ---------------------
diff --git a/aleksis/core/mixins.py b/aleksis/core/mixins.py
index e734b40a8..2eef69a46 100644
--- a/aleksis/core/mixins.py
+++ b/aleksis/core/mixins.py
@@ -27,7 +27,7 @@ from dynamic_preferences.types import FilePreference
 from guardian.admin import GuardedModelAdmin
 from guardian.core import ObjectPermissionChecker
 from jsonstore.fields import IntegerField, JSONFieldMixin
-from material.base import Layout, LayoutNode
+from material.base import Fieldset, Layout, LayoutNode
 from polymorphic.base import PolymorphicModelBase
 from polymorphic.managers import PolymorphicManager
 from polymorphic.models import PolymorphicModel
@@ -449,6 +449,20 @@ class ExtensibleForm(ModelForm, metaclass=_ExtensibleFormMetaclass):
         cls.base_layout.append(node)
         cls.layout = Layout(*cls.base_layout)
 
+        visit_nodes = [node]
+        while visit_nodes:
+            current_node = visit_nodes.pop()
+            if isinstance(current_node, Fieldset):
+                visit_nodes += node.elements
+            else:
+                field_name = (
+                    current_node if isinstance(current_node, str) else current_node.field_name
+                )
+                field = fields_for_model(cls._meta.model, [field_name])[field_name]
+                cls._meta.fields.append(field_name)
+                cls.base_fields[field_name] = field
+                setattr(cls, field_name, field)
+
 
 class BaseModelAdmin(GuardedModelAdmin, ObjectPermissionsModelAdmin):
     """A base class for ModelAdmin combining django-guardian and rules."""
-- 
GitLab