I'm using django-crispy-forms
for nicely rendered forms.
For one of my forms, I had to make some custom adjustments and am now wondering how to properly validation errors that don't belong to a specific field but to the whole form.
Specifically, my form contains a start and end date:
# forms.py
class PlotForm(forms.Form):
start_date = forms.DateField(initial=last_month, widget=forms.widgets.DateInput(attrs={'type': 'date'}))
end_date = forms.DateField(initial=datetime.date.today, widget=forms.widgets.DateInput(attrs={'type': 'date'}))
def clean(self):
cleaned_data = super().clean()
start_date = cleaned_data.get('start_date')
end_date = cleaned_data.get('end_date')
if start_date > end_date:
raise forms.ValidationError("Start date must not be before end date.")
return start_date
To check that the end date is not before the start date, I use clean(self)
.
However, the error is never displayed.
<form method="post">
{% csrf_token %}
<div class="row">
<div class="col-6">
{{ form.start_date|as_crispy_field }}
</div>
<div class="col-6">
{{ form.end_date|as_crispy_field }}
</div>
</div>
<button type="submit" class="btn btn-primary">Submit</button>
</form>
I can fix this by adding {{ form.errors }}
but that looks really ugly. Is there any simple way to nicely render form-related validation errors with crispy
?
The field-related errors are shown nicely.
You can use the |as_crispy_errors
template filters [readthedocs]:
<form method="post">
{% csrf_token %}
{{ form|as_crispy_errors }}
<div class="row">
<div class="col-6">
{{ form.start_date|as_crispy_field }}
</div>
<div class="col-6">
{{ form.end_date|as_crispy_field }}
</div>
</div>
<button type="submit" class="btn btn-primary">Submit</button>
</form>
This template filter will:
Renders only form errors the same way as
django-crispy-forms
.