Reputation: 4139
Tried using this (Django: How to set DateField to only accept Today & Future dates) SO post to have form raise error in template when a date field is given value less than current date (which, based on another SO answer (https://stackoverflow.com/a/22513989/8236733), I thought was done via the form field validators (see https://docs.djangoproject.com/en/2.0/ref/forms/validation/#cleaning-a-specific-field-attribute)). However, this does not seem to be working when inputting supposedly invalid values in the form template.
forms.py:
import datetime
from django import forms
from .models import Post
class MyForm(forms.Form):
title = forms.CharField(max_length=100, required=True, help_text='Give a title',
widget=forms.TextInput(attrs={'size': '50rem'}))
post = forms.CharField(max_length=280, required=True,
widget=forms.Textarea(attrs={'rows': 5}))
expire_date = forms.DateField(
widget=forms.TextInput(attrs=
{
'class':'datepicker', # to use jquery datepicker
}),
required=True
)
expire_time = forms.TimeField(
input_formats=['%H:%M %p'],
widget=forms.TextInput(attrs=
{
'class':'timepicker', # to use jquery timepicker
}),
required=True)
class Meta:
model = Post
fields = ('title', 'post', 'expire_date', 'expire_time',)
def clean_date(self): # see https://docs.djangoproject.com/en/dev/ref/forms/validation/#cleaning-a-specific-field-attribute
date = self.cleaned_data['expire_date']
print(date)
if date < datetime.date.today():
raise forms.ValidationError("The date cannot be in the past!")
return date
Relevant template snippet:
<form method="post">
{% csrf_token %}
{% for field in listing_form %}
<p>
{{ field.label_tag }}
<div class="ui input">{{ field }}</div>
{% if field.help_text %}
<small class="ui inverted">{{ field.help_text }}</small>
{% endif %}
{% for error in field.errors %}
<p style="color: red">{{ error }}</p>
{% endfor %}
</p>
{% endfor %}
<button class="ui inverted button" type="submit">submit</button>
<div class="ui divider"></div>
</small>
</form>
Attempting to submit this form with some past date does not raise any error in the teplate and the form's is_valid() method raises no error in the backend view.
New to django, so is there something I am missing here? Do I need to somehow attach the validation method to the particular field in some way?
Upvotes: 0
Views: 718
Reputation: 4139
Apparently it is important that the form method for cleaning / validating a particular form field follow a particular naming convention: clean_<field name>
. This is shown implicitly in the docs (https://docs.djangoproject.com/en/2.0/ref/forms/validation/#cleaning-a-specific-field-attribute), but never stated outright. Changing the clean_...
method in the form class in the original post to have the following code seems to have fixed the problem.
class MyForm(forms.Form):
....
expire_date = forms.DateField(
widget=forms.TextInput(attrs=
{
'class':'datepicker', # to use jquery datepicker
}),
required=True
)
....
class Meta:
model = Post
fields = ('title', 'post', 'expire_date', 'expire_time',)
def clean_expire_date(self):
date = self.cleaned_data['expire_date']
print(date)
if date < datetime.date.today():
raise forms.ValidationError("The date cannot be in the past!")
return date
If anyone knows where in the docs this naming convention is more explicitly specified, please let me know.
Upvotes: 1