Django form.is_valid() 总是假的

Posted

技术标签:

【中文标题】Django form.is_valid() 总是假的【英文标题】:Django form.is_valid() always false 【发布时间】:2014-01-15 02:10:13 【问题描述】:

我正在编写登录代码。当我手动编写表单时,我得到了它的工作。

以下代码有效:

views.py

def login_view(request):
    if request.method == 'GET':
        return render(request, 'app/login.htm')
    if request.method == 'POST':
        username = request.POST.get('username', '')
        password = request.POST.get('password', '')
        user = auth.authenticate(username=username, password=password)
        if user is None:
            return HttpResponseRedirect(reverse('error'))
        if not user.is_active:
            return HttpResponseRedirect(reverse('error'))

        # Correct password, and the user is marked "active"
        auth.login(request, user)
        # Redirect to a success page.
        return HttpResponseRedirect(reverse('home'))

模板:

<form method="post" action="% url 'login'  %">
    % csrf_token %
    <p><label for="id_username">Username:</label> <input id="id_username" type="text" name="username" maxlength="30" /></p>
    <p><label for="id_password">Password:</label> <input type="password" name="password" id="id_password" /></p>

    <input type="submit" value="Log in" />
    <input type="hidden" name="next" value="" />
</form>

太棒了!但现在我想用 Django 的表单做同样的事情。

下面的代码不起作用,因为我总是得到 is_valid() == False。

views.py:

def login_view(request):
    if request.method == 'POST':
        form = AuthenticationForm(request.POST)
        print form.is_valid(), form.errors, type(form.errors)
        if form.is_valid():
            ## some code....
            return HttpResponseRedirect(reverse('home'))
        else:
            return HttpResponseRedirect(reverse('error'))
    else:
        form = AuthenticationForm()
    return render(request, 'app/login.htm', 'form':form)

模板:

<form action="% url 'login' %" method="post">% csrf_token %
 form.as_p 
<input type="submit" value="Submit" />

*** 上有很多人抱怨他们得到的 is_valid 总是假的。我已经阅读了所有这些帖子,据我所知,我没有犯任何这些错误。我发现了一个新错误:-)

编辑:我在代码中添加了打印。打开登录视图并提交时的输出是

[27/Dec/2013 14:01:35] "GET /app/login/ HTTP/1.1" 200 910
False  <class 'django.forms.util.ErrorDict'>
[27/Dec/2013 14:01:38] "POST /app/login/ HTTP/1.1" 200 910

所以 is_valid() 为 False,但 form.errors 为空。

【问题讨论】:

出现错误时为什么要重定向?如果您不这样做,表单将与错误消息一起重新呈现,您将能够确切地看到表单无效的原因。完全删除第一个 else 子句。 我删除了你说的第一个else子句,提交后,表单只是再次重新渲染,清除。 【参考方案1】:

事实证明,Maxime 是对的(抱歉)——你确实需要 data 参数:

form = AuthenticationForm(data=request.POST)

不过,这样做的原因是 AuthenticationForm 覆盖了 __init__ 的签名,以期望 request 作为第一个位置参数。如果您明确提供 data 作为 kwarg,它将起作用。

(不过,您仍然应该省略在错误时重定向的 else 子句:在这种情况下,让表单重新呈现错误是最佳做法。)

【讨论】:

没错,解决了它。你能引导我了解导致你得出这个结论的思考过程吗?你知道,关于教一个人如何钓鱼的事情...... 我看了the source code。虽然如果我现在在一台带有 Python shell 的计算机上,我会在那里导入类并完成help(AuthenticationForm),这会给我签名。 你知道,现在我经常去看源代码... :-) 已经快 3 年了。天哪。【参考方案2】:

查看form.errors,这将帮助您找出原因。

【讨论】:

是的,在其他类似问题中人们也这么说。我试了一下,form.errors 是空的。它是 django.forms.util.ErrorDict 类型的对象,但什么都不包含。【参考方案3】:

如果出现这种情况,你没有选择(我试图使用引导模式,但它只是不工作),我必须这样做,否则模式总是会触发,即使表单有没有问题(默认情况下 is_valid 始终为 False

我需要什么:

单击按钮时显示模式 如果出现错误,显示在同一页面上,模态,与错误。

在模态模板中:

% if not brand_form.is_valid and brand_form.errors %
        <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
        <script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.2/js/bootstrap.min.js"></script>
        <script type="text/javascript">
             $(window).on('load', (function() 
                $('#brandAddModal').modal('show');
             ));
        </script>
                    
           brand_form.non_field_errors 
% endif %

在视图中:

def add_brand_form(request):
    form = BrandForm()
    if request.method == 'POST':
        form = BrandForm(data=request.POST)
        if form.is_valid():
            return HttpResponseRedirect('/home')
        else:
            return render(request, template_name='home.html', context='brand_form':form)
        
    return render(request, template_name='modal_add_brand.html', context='brand_form':form)

【讨论】:

以上是关于Django form.is_valid() 总是假的的主要内容,如果未能解决你的问题,请参考以下文章

Django 表单不运行 form.is_valid

当值为空时,Django modelSerializer form.is_valid() 为真

Django 消费者(Django 频道)中的表单数据验证(相当于 form.is_valid)

Django:form.is_valid 检查后,cleaned_data 缺少图像字段

Django form.is_valid() 失败的基于类的视图 - Form、SingleObject、DetailMixins

Form验证随笔 | Django