diff --git a/cms/forms.py b/cms/forms.py index 428ea12..8d1612d 100644 --- a/cms/forms.py +++ b/cms/forms.py @@ -47,6 +47,9 @@ class SectionForm(forms.ModelForm): self.fields['type'].choices = self._meta.model.TYPES self.fields['type'].initial = self._meta.model.TYPES[0][0] + self.fields['type'].widget.attrs['class'] = 'type' + self.fields['type'].widget.attrs['data-form'] = self.prefix + def delete(self): instance = super().save() instance.delete() @@ -83,18 +86,13 @@ class SectionForm(forms.ModelForm): #SectionFormSet = inlineformset_factory(Page, Section, form=SectionForm, extra=1) -def get_view(section): - if section: - return section.__class__.view_class() - class BaseSectionFormSet(forms.BaseInlineFormSet): - '''Potentially nested formset based on - https://www.yergler.net/2013/09/03/nested-formsets-redux/ + '''If a swappable Section model defines one-to-many fields, (i.e. has + foreign keys pointing to it) formsets will be generated for the + related models and stored in the form.formsets array. - If a Section subclass provides a 'formset_class' attribute, the - section form generated for the edit page will be given a 'formset' - attribute. This way, sections can customize their edit form to - request additional information. + Based on this logic for nested formsets: + https://www.yergler.net/2013/09/03/nested-formsets-redux/ Typical usecases could be: - an images section that displays multiple images @@ -106,22 +104,23 @@ class BaseSectionFormSet(forms.BaseInlineFormSet): def add_fields(self, form, index): super().add_fields(form, index) section = form.instance - view = get_view(section) - if hasattr(view, 'formset_class'): - form.formset = view.formset_class( - instance=section, - data=form.data if self.is_bound else None, - files=form.files if self.is_bound else None, - prefix=f'{form.prefix}-{view.formset_class.get_default_prefix()}') - #raise ValueError(form.formset) - + form.formsets = [] + for field in section._meta.get_fields(): + if field.one_to_many: + formset = forms.inlineformset_factory(Section, field.related_model, fields='__all__', extra=1)( + instance=section, + data=form.data if self.is_bound else None, + files=form.files if self.is_bound else None, + prefix=f'{form.prefix}-{field.name}') + formset.name = field.name + form.formsets.append(formset) def is_valid(self): result = super().is_valid() if self.is_bound: for form in self.forms: - if hasattr(form, 'formset'): - result = result and form.formset.is_valid() + for formset in form.formsets: + result = result and formset.is_valid() return result def save(self, commit=True): @@ -131,6 +130,12 @@ class BaseSectionFormSet(forms.BaseInlineFormSet): form.formset.save(commit=commit) return result + def get_form_kwargs(self, index): + kwargs = super().get_form_kwargs(index) + kwargs.update({'label_suffix': ''}) + return kwargs + + SectionFormSet = forms.inlineformset_factory( parent_model = Page, model = Section, @@ -138,3 +143,9 @@ SectionFormSet = forms.inlineformset_factory( formset = BaseSectionFormSet, extra=1, ) + +# class ImagesForm(forms.ModelForm): +# class Meta: +# model = SectionImage +# exclude = ['section'] +# ImagesFormSet = forms.inlineformset_factory(Section, SectionImage, form=ImagesForm, extra=3) diff --git a/cms/static/cms/add.png b/cms/static/cms/add.png new file mode 100644 index 0000000..98e41bf Binary files /dev/null and b/cms/static/cms/add.png differ diff --git a/cms/static/cms/add_small.png b/cms/static/cms/add_small.png new file mode 100644 index 0000000..1ad765f Binary files /dev/null and b/cms/static/cms/add_small.png differ diff --git a/cms/static/cms/edit.png b/cms/static/cms/edit.png index a9ae4a1..96b03a3 100644 Binary files a/cms/static/cms/edit.png and b/cms/static/cms/edit.png differ diff --git a/cms/static/cms/edit.svg b/cms/static/cms/edit.svg deleted file mode 100644 index 47eca6e..0000000 --- a/cms/static/cms/edit.svg +++ /dev/null @@ -1,75 +0,0 @@ - - - - - - image/svg+xml - - - - - - - - - - - - - - - diff --git a/cms/static/cms/ok.svg b/cms/static/cms/ok.svg deleted file mode 100644 index 18b4972..0000000 --- a/cms/static/cms/ok.svg +++ /dev/null @@ -1,60 +0,0 @@ - - - - - - image/svg+xml - - - - - - - - - diff --git a/cms/static/cms/save.png b/cms/static/cms/save.png new file mode 100644 index 0000000..9618d8f Binary files /dev/null and b/cms/static/cms/save.png differ diff --git a/cms/templates/cms/edit.html b/cms/templates/cms/edit.html index d7b0598..c095632 100644 --- a/cms/templates/cms/edit.html +++ b/cms/templates/cms/edit.html @@ -4,131 +4,104 @@ {% block title %}{% trans 'Edit' %} {{form.instance}}{% endblock %} {% block content %} -
- {% csrf_token %} - {{form.media}} +
- {% if form %} -
-
- {% if form.non_field_errors %} -
- {{form.non_field_errors}} -
- {% elif form.errors or formset.errors %} -
- {% trans 'Please correct the error(s) below and save again' %} -
- {% endif %} - {% for field in form %} - {% if field.field.widget.input_type == 'checkbox' %} - {% include 'cms/formfield_checkbox.html' with field=field %} - {% else %} - {% include 'cms/formfield.html' with field=field %} - {% endif %} - {% endfor %} + + {% csrf_token %} + {{form.media}} + + {% if form.errors or formset.errors %} +
+ {% trans 'Please correct the error(s) below and save again' %}
-
- {% endif %} + {% endif %} + {% for field in form %} + {% include 'cms/formfield.html' with field=field %} + {% endfor %} - {% if formset %} -
+
{{formset.management_form}} {% for form in formset %} -
+
{{form.media}} {% for field in form.hidden_fields %} {{field}} {% endfor %} -
-
-
- {% for field in form.visible_fields %} - {% if field.name == 'DELETE' and not form.instance.pk %} - - {% elif field.field.widget.input_type == 'checkbox' %} - {% include 'cms/formfield_checkbox.html' with field=field counter=forloop.parentloop.counter0 %} - {% else %} - {% include 'cms/formfield.html' with field=field counter=forloop.parentloop.counter0 %} - {% endif %} - {% endfor %} -
- {{form.formset.management_form}} - {% for form in form.formset %} -
+ {% for field in form.visible_fields %} +
+ {% include 'cms/formfield.html' with field=field %} +
+ {% endfor %} + + {% for formset in form.formsets %} +
+ {{formset.management_form}} + {% for form in formset %} +
+ {{form.media}} + {% for field in form.hidden_fields %} + {{field}} + {% endfor %} {% for field in form.visible_fields %} - {% if field.name == 'DELETE' and not form.instance.pk %} - - {% elif field.field.widget.input_type == 'checkbox' %} - {% include 'cms/formfield_checkbox.html' with field=field counter=forloop.parentloop.counter0 %} - {% else %} - {% include 'cms/formfield.html' with field=field counter=forloop.parentloop.counter0 %} - {% endif %} + {% include 'cms/formfield.html' with field=field %} {% endfor %}
{% endfor %} +
-
+ {% endfor %}
{% endfor %} +
- -
-
- + -
-
- {% endif %} -
- -
- - +
+ +
+ +
{% endblock %} {% block extrabody %} {% endblock %} diff --git a/cms/templates/cms/formfield.html b/cms/templates/cms/formfield.html index bfbcb5e..9911941 100644 --- a/cms/templates/cms/formfield.html +++ b/cms/templates/cms/formfield.html @@ -1,14 +1,26 @@ -
-
- {{field.errors}} -
-
- {{field.label_tag}} -
-
- {{field}} -
-
+{% if field.name == 'DELETE' and not form.instance.pk %} + +{% else %} +
+
+ {{field.errors}} +
+ + {% if field.field.widget.input_type == 'checkbox' %} +
+ {{field}} {{field.label_tag}} +
+ {% else %} +
+ {{field.label_tag}} +
+
+ {{field}} +
+ {% endif %} + +
{{field.help_text}} +
-
+{% endif %} diff --git a/cms/templates/cms/formfield_checkbox.html b/cms/templates/cms/formfield_checkbox.html deleted file mode 100644 index 385c8d9..0000000 --- a/cms/templates/cms/formfield_checkbox.html +++ /dev/null @@ -1,11 +0,0 @@ -
-
- {{field.errors}} -
-
- {{field}} {{field.label_tag}} -
-
- {{field.help_text}} -
-
diff --git a/cms/views.py b/cms/views.py index 521e1e4..ad66296 100644 --- a/cms/views.py +++ b/cms/views.py @@ -157,8 +157,7 @@ class EditPage(UserPassesTestMixin, edit.ModelFormMixin, base.TemplateResponseMi def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) - if 'formset' not in context: - context['formset'] = SectionFormSet(instance=self.object, form_kwargs={'label_suffix': ''}) +# context['formset'] = SectionFormSet(instance=self.object, form_kwargs={'label_suffix': ''}) fields_per_type = {} for model, _ in Section.TYPES: ctype = ContentType.objects.get( @@ -180,10 +179,13 @@ class EditPage(UserPassesTestMixin, edit.ModelFormMixin, base.TemplateResponseMi def get(self, request, *args, **kwargs): self.object = self.get_object() - return self.render_to_response(self.get_context_data()) + formset = self.get_formset() + return self.render_to_response(self.get_context_data(formset=formset)) def get_formset(self): - return SectionFormSet(self.request.POST, self.request.FILES, instance=self.object) + if self.request.POST: + return SectionFormSet(self.request.POST, self.request.FILES, instance=self.object) + return SectionFormSet(instance=self.object) def post(self, request, *args, **kwargs): self.object = self.get_object()