通过查看文档,似乎表单clean()方法仅用于执行与语法相关的轻量级验证,例如检查电子邮件地址是以“.com”或“.edu”结尾,还是确保用户从“挑选前三个最喜欢的电视节目”列表中选择不超过三个项目。
我正在开发一个允许用户设置密码的应用程序,我想确保他们的密码不包含他们的登录名或真实姓名,而clean()方法似乎不正确从设计的角度来看,以及clean()方法无法访问会话数据的实际限制,都可以进行这种检查。
进行更多重量级验证的最佳位置在哪里?如果我在调用form.is_valid()
后在视图中进行了一些自定义检查,是否有办法恢复标准表单错误处理?
我知道代码可能如下所示:
def process_login(request):
"""Display or process the login form."""
if request.method == 'POST':
form = LoginForm(request.POST)
if form.is_valid():
password = form.cleaned_data['password']
if password_is_bad(password, request):
# what now?
答案 0 :(得分:3)
还有特定于字段的验证挂钩:clean_$fieldname
。请参阅django docs this section中的详细信息。
更新:至于将会话信息传递给表单,可以通过属性分配轻松完成:
form = LoginForm(request.POST)
form.session = request.session
然后您可以self.session
方法访问clean_password
。
答案 1 :(得分:3)
我更喜欢在表单中进行所有验证。如果我在考虑对象职责方面,我认为表单是描述表单组件的对象,以及如何在HTML表单和有效 python对象之间进行转换,其中“有效” “包括特定于应用程序的要求。
如果表单需要通常无法访问的信息,我会将该信息传递给表单的构造函数。未经测试的代码如下:
class MyForm(Form):
def __init__(self, session, *args, **kwargs):
self.session = session
super(MyForm, self).__init__(self, *args, **kwargs)
def clean(self):
# does something with self.session
这种方法的优点是,您的视图通常可以非常通用,通常只是将实例化的表单对象传递给自定义通用视图。
答案 2 :(得分:-1)
如果您确实想要在视图中验证表单的某些部分,那么您可以引发ValidationError异常,这将使用户返回并显示您的错误消息。
from django.forms.util import ValidationError
if len( form.cleaned_data['password'] ) < 5:
raise ValidationError('You have to type at least five characters')