Django高级表单验证方法?

时间:2011-05-27 17:01:50

标签: django validation

通过查看文档,似乎表单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?

3 个答案:

答案 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')