Description
I am using code resembling the following (I omitted a lot of additional fields, labels, help texts, etc to make the example more concise and in turn hopefully more readable). The field email
is defined in the PersonModel
whilst email_repeated
is a "virtual" field declared and processed within the Person
form.
Another Note: I am in the progress of porting our forms to the form wizard, thus, some code might not be necessary any more, i.e. the back button handling inside __init__
.
class Person(ModelForm):
email_repeated = EmailField(
required=False,
widget=EmailInput(),
)
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.helper = FormHelper()
self.helper.field_template = "bootstrap5/field.html"
self.helper.help_text_inline = False
self.helper.form_method = "post"
self.helper.form_tag = False
self.helper.layout = Layout(
Fieldset(
Div("email"),
Div("email_repeated"),
),
Div(
Submit("prev", _("⎗ Previous")),
Submit("next", _("⎘ Next")),
),
)
# pretend that fields are required for back button management
self.fields["email"].required = False
self.fields["email"].show_required = True
self.fields["email_repeated"].required = False
self.fields["email_repeated"].show_required = True
def clean_email_repeated(self):
print(
f"clean_email_repeated {self.data.get('email')} -> {self.data.get('email_repeated')} ({self.data})"
)
return self.data.get("email_repeated")
def clean_email(self):
email = self.get("email")
email_repeated = self.data.get("email_repeated")
print(f"clean_email {email} -> {email_repeated} ({self.data})")
if email != email_repeated:
self.add_error("email", "E-Mail Error")
return email
def clean(self):
clean_data = super().clean()
print(f"clean {self.data}")
return clean_data
class Meta:
model = PersonModel
fields = [
"email",
"email_repeated",
]
exclude = ["email_verified"]
widgets = {
"email_repeated": EmailInput(),
}
When using the form in its own view clean_email_repeated
prints email
as well as email_repeated
, when using SessionWizardView
only email
is printed, email_repeated
is None
.
Likewise, clean_email_repeated
prints both fields correctly when the form in its own view, but prints None
when printing email
and clean_email_repeated
.
clean
on the other hand prints both fields correctly. Any hints to what exactly is going on here? Am I to blame? Is this a bug and more importantly, is there a fix that allows me to keep the logic of cleaning the fields separate, without having to couple the forms to SessionWizardView
?
// edit: using cleaned_data to access the data also returns None