Added class to abstract form generation
ci/woodpecker/push/build Pipeline was successful Szczegóły
ci/woodpecker/pr/build Pipeline failed Szczegóły

pull/18/head
mtyton 2023-10-12 22:59:04 +02:00
rodzic dc25fa01a7
commit 2ab84212b6
5 zmienionych plików z 162 dodań i 17 usunięć

Wyświetl plik

@ -0,0 +1,25 @@
from collections.abc import Mapping
from typing import Any
from django import forms
from django.forms.utils import ErrorList
class DynamicForm(forms.Form):
FIELD_TYPE_MAPPING = {
"singleline": forms.CharField(max_length=255, widget=forms.TextInput(attrs={"class": "form-control"})),
"multiline": forms.CharField(max_length=255, widget=forms.Textarea(attrs={"class": "form-control"})),
"email": forms.EmailField(max_length=255, widget=forms.EmailInput(attrs={"class": "form-control"})),
"number": forms.IntegerField(widget=forms.NumberInput(attrs={"class": "form-control"})),
"url": forms.URLField(max_length=255, widget=forms.URLInput(attrs={"class": "form-control"})),
"checkbox": forms.BooleanField(required=False, widget=forms.CheckboxInput(attrs={"class": "form-control"})),
"checkboxes": forms.MultipleChoiceField(required=False, widget=forms.CheckboxSelectMultiple(attrs={"class": "form-control"})),
"dropdown": forms.ChoiceField(widget=forms.Select(attrs={"class": "form-control"})),
}
def __init__(self, field_list, *args, **kwargs) -> None:
self.page = kwargs.pop("page")
self.user = kwargs.pop("user")
super().__init__(*args, **kwargs)
for field in field_list:
self.fields[field.clean_name] = self.FIELD_TYPE_MAPPING[field.field_type]

Wyświetl plik

@ -1,4 +1,4 @@
# Generated by Django 4.1.11 on 2023-10-10 20:22
# Generated by Django 4.1.11 on 2023-10-12 17:23
import django.core.serializers.json
from django.db import migrations, models
@ -19,7 +19,17 @@ class Migration(migrations.Migration):
migrations.CreateModel(
name="CustomEmailForm",
fields=[
("id", models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name="ID")),
(
"page_ptr",
models.OneToOneField(
auto_created=True,
on_delete=django.db.models.deletion.CASCADE,
parent_link=True,
primary_key=True,
serialize=False,
to="wagtailcore.page",
),
),
("intro", wagtail.fields.RichTextField(blank=True)),
("thank_you_text", wagtail.fields.RichTextField(blank=True)),
("allow_attachments", models.BooleanField(default=False)),
@ -30,7 +40,7 @@ class Migration(migrations.Migration):
options={
"abstract": False,
},
bases=(wagtail.contrib.forms.models.FormMixin, models.Model),
bases=(wagtail.contrib.forms.models.FormMixin, "wagtailcore.page"),
),
migrations.CreateModel(
name="EmailFormSubmission",

Wyświetl plik

@ -5,7 +5,6 @@ from django.conf import settings
from django.utils.formats import date_format
from modelcluster.fields import ParentalKey
from modelcluster.models import ClusterableModel
from wagtail.admin.panels import (
FieldPanel, FieldRowPanel,
InlinePanel, MultiFieldPanel
@ -19,9 +18,10 @@ from wagtail.contrib.forms.models import (
)
from mailings.models import send_mail
from dynamic_forms.forms import DynamicForm
class Form(FormMixin, ClusterableModel):
class Form(FormMixin, Page):
intro = RichTextField(blank=True)
thank_you_text = RichTextField(blank=True)
allow_attachments = models.BooleanField(default=False)
@ -39,6 +39,17 @@ class Form(FormMixin, ClusterableModel):
], "Email"),
]
def get_form_class(self):
return DynamicForm
def get_form(self, *args, **kwargs):
form_class = self.get_form_class()
form_params = self.get_form_parameters()
form_params.update(kwargs)
print(form_params)
fields = self.get_form_fields()
return form_class(field_list=fields, *args, **form_params)
class Meta:
abstract = True

Wyświetl plik

@ -5,14 +5,17 @@
{% block content %}
<h1>{{ page.title }}</h1>
<p class="meta">{{ page.date }}</p>
{% if form %}
<div>{{ page.intro|richtext }}</div>
<form action="{% pageurl page %}" method="POST">
{% csrf_token %}
{% for field in form %}
{{field.label}} {{field}}
<div class="body">{{ page.body|richtext }}</div>
{% for item in page.gallery_images.all %}
<div style="float: left; margin: 10px">
{% image item.image fill-320x240 %}
<p>{{ item.caption }}</p>
</div>
{% endfor %}
{% endfor %}
<input type="submit">
</form>
{% else %}
<div>You can fill in the from only one time.</div>
{% endif %}
{% endblock %}

Wyświetl plik

@ -1,5 +1,101 @@
from django.test import TestCase
# Create your tests here.
class ComfyEmailFormMixin(TestCase):
...
from dynamic_forms.models import (
CustomEmailForm,
EmailFormField
)
class CustomEmailFormTestCase(TestCase):
def setUp(self):
self.form = CustomEmailForm.objects.create(
from_address="comfy-test@egalitare.pl",
to_address="comfy-dest@egalitare.pl",
subject="Test Form", allow_attachments=False
)
EmailFormField.objects.create(
label="Name",
field_type="singleline",
required=True,
form=self.form
)
EmailFormField.objects.create(
label="Message",
field_type="multiline",
required=True,
form=self.form
)
EmailFormField.objects.create(
label="Email",
field_type="email",
required=True,
form=self.form
)
EmailFormField.objects.create(
label="Number",
field_type="number",
required=True,
form=self.form
)
EmailFormField.objects.create(
label="URL",
field_type="url",
required=True,
form=self.form
)
EmailFormField.objects.create(
label="Checkbox",
field_type="checkbox",
required=True,
form=self.form
)
EmailFormField.objects.create(
label="Checkboxes",
field_type="checkboxes",
required=True,
choices="a,b,c",
form=self.form
)
EmailFormField.objects.create(
label="Dropdown",
field_type="dropdown",
required=True,
choices="a,b,c",
form=self.form
)
EmailFormField.objects.create(
label="MultiSelect",
field_type="multiselect",
required=True,
choices="a,b,c",
form=self.form
)
EmailFormField.objects.create(
label="Radio",
field_type="radio",
required=True,
choices="a,b,c",
form=self.form
)
EmailFormField.objects.create(
label="Date",
field_type="date",
required=True,
form=self.form
)
EmailFormField.objects.create(
label="DateTime",
field_type="datetime",
required=True,
form=self.form
)
EmailFormField.objects.create(
label="Hidden",
field_type="hidden",
required=True,
form=self.form
)
def test_create_form_submission_without_files(self):
...