form_invalid()
是Django中FormMixin提供的一个方法,用于处理表单验证不通过的情况。当表单验证失败时,Django会调用form_invalid()
方法执行下面的一些操作:
- 利用
form_class
属性创建一个表单对象 - 根据表单对象,重定向向当前URL并附带上包括验证结果信息的GET参数
- 渲染模板
如果form_invalid()
不被显式地实现,Django默认会返回一个HttpResponseBadRequest
。
在form_invalid()
方法中,我们可以添加自己的逻辑来处理特定的表单验证错误。每次在表单提交过程中,如果验证不成功就会调用form_invalid()
方法。
下面给出两个实例:
实例一
我们先假设有一个简单的联系我们表单,表单有以下字段:姓名(Name),电子邮件(Email),主题(Subject)和消息正文(Message)。我们来看一下如何验证一封有效的邮件地址。
# views.py
from django.core.mail import send_mail
from django.urls import reverse_lazy
from django.views.generic.edit import FormView
from .forms import ContactForm
class ContactView(FormView):
template_name = "contact.html"
form_class = ContactForm
success_url = reverse_lazy('contact_success')
def form_valid(self, form):
subject = form.cleaned_data['subject']
message = form.cleaned_data['message']
from_email = form.cleaned_data['from_email']
send_mail(subject, message, from_email, ['your-email@example.com'], fail_silently=False)
return super().form_valid(form)
def form_invalid(self, form):
form.add_error('from_email', 'Please enter valid email address.')
return super().form_invalid(form)
在这个例子中,form_invalid()
方法被用来添加邮件地址验证错误消息。如果邮件地址无效,表单将重新呈现,并且一个带着错误消息的form实例将被传递给模板。
<!-- contact.html -->
<form method="POST">
{% csrf_token %}
{{ form.as_p }}
<input type="submit" value="Submit">
{% if form.errors %}
<p>Email address is invalid</p>
{% endif %}
</form>
实例二
假设你想要在用户修改一个表单的时候,要求他们输入一个确认密码。可以在表单中添加一个confirm_password
字段,然后在form_valid()
方法中检查输入的密码和确认密码是否相等。如果不相等,则调用form_invalid()
方法。
# views.py
from django.urls import reverse_lazy
from django.views.generic.edit import UpdateView
from django.utils.decorators import method_decorator
from django.contrib.auth.decorators import login_required
from .models import UserProfile
from .forms import UserProfileForm
@method_decorator(login_required, name='dispatch')
class UserProfileUpdate(UpdateView):
model = UserProfile
form_class = UserProfileForm
template_name = 'profile/update.html'
success_url = reverse_lazy('profile:detail')
def form_valid(self, form):
if form.cleaned_data.get('password') != form.cleaned_data.get('confirm_password'):
return self.form_invalid(form)
return super().form_valid(form)
def form_invalid(self, form):
form.add_error('confirm_password', "Passwords don't match")
return super().form_invalid(form)
在这个实例中,form_invalid()
方法被用来添加表单密码确认错误消息,并重新呈现包含错误消息的表单。