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 modelSerializer form.is_valid() 为真
Django 消费者(Django 频道)中的表单数据验证(相当于 form.is_valid)
Django:form.is_valid 检查后,cleaned_data 缺少图像字段
Django form.is_valid() 失败的基于类的视图 - Form、SingleObject、DetailMixins