我有一张表格,只有在清理后才需要验证.

当你跑form.is_valid()米的时候会发生什么?表单是否已清理,然后已清理版本的表单是否已验证?

我现在得到的行为是,如果我的字段在清理之前没有通过验证,即使清理可以让它通过,is_valid()也会返回False.

我做错什么了吗?

代码:

# View
class ContactForm(forms.Form):
    message = forms.CharField(widget=forms.Textarea, max_length=5)

    def clean_message(self):
        message = self.cleaned_data['message']
        return message.replace('a', '') # remove all "a"s from message

def contact(request):
    if request.method == 'POST':
        if form.is_valid():
            return HttpResponseRedirect('/contact/on_success/')
        else:
            return HttpResponseRedirect('/contact/on_failure/')

如果消息少于5个字符NOT(包括a),我希望form.is_valid()返回True

有可能在to_python()之后但在run_validators()之前跑clean_<fieldname>()吗?还是我应该用其他方式来做?

推荐答案

我认为表单验证的过程(以及正确的顺序)实际上是well documented.

你介意分享你的代码吗?每个formfield上都有一个clean方法,负责运行to_pythonvalidaterun_validators(按此顺序).to_python接受小部件的原始值,将其强制为python类型,validate接受强制值并运行特定于字段的验证.

Answer updated with regards to the code given

clean_message是在所有其他验证(如to_pythonvalidate,最重要的是run_validators)运行之后调用的.我认为最后一个方法将判断max_length约束是否未被违反.所以之后更改数据不会有任何影响.

解决办法是在这里提高ValidationError分.删除max_length将避免对输入长度进行任何验证.

class ContactForm(forms.Form):
    message = forms.CharField(widget=forms.Textarea)

    def clean_message(self):
        message = self.cleaned_data['message']
        message = message.replace('a', '') # remove all "a"s from message
        if len(message) >= 5:
            raise ValidationError('Too many characters ...')
        return message

Django相关问答推荐

如何从Django';S模型中的方法中检索值?

Django 中主键的隐式 UUID 自动字段

Django 隐藏特定人员的媒体文件链接

Django ImproperlyConfigured: AUTH_USER_MODEL指向尚未安装的模型'users.User'

如何在 Fargate 容器中运行的 Django 中使用 AWS SES?

根据当前对象中的多对多字段过滤对象

Django Rest Framework 速率限制动态基于用户类型

如何在 Django 模型中存储元组列表

Django获取具有值的相关对象的计数并将其添加到注释中

Django Query 在基于通用类的 UpdateView 中重复了 2 次

PyCharm:强制 Django 模板语法突出显示

Django-Registration:邮箱作为用户名

文档中的 Mongoengine creation_time 属性

可以在基于 Django 类的视图中设置实例变量吗?

virtualenv(python3.4), pip install mysqlclient 错误

测试 Django 信号的正确方法

如何从 django 的 db 模型中获取字段类型字符串

Django 默认=timezone.now + delta

Django post_save 在不覆盖模型 save() 的情况下防止递归

Python - 覆盖 __init__ 的最干净方法,其中在 super() 调用之后必须使用可选的 kwarg?