Django登录模板{% if form.errors %}放置位置及执行逻辑疑问
前置说明
这类框架学习类问题属于正常提问范畴,没有违规。
问题解答
出现这个误解的核心原因是搞反了Django的请求处理顺序:模板里的代码从上到下渲染时,后端的表单校验逻辑早就执行完了,不存在“模板在表单处理前就做错误校验”的情况。
Django处理登录请求的完整流程按以下顺序执行:
- 第一步:请求先到达后端对应的登录视图(你这里用的是Django内置的登录视图,逻辑已经封装完成),模板此时还没开始加载。
- 第二步:视图判断请求类型做对应处理:
- 如果是用户第一次打开登录页的GET请求:视图会生成一个空的、没有绑定任何提交数据的表单对象,这个对象的
errors属性为空,之后会被传给模板。 - 如果是用户填完信息点提交的POST请求:视图会先把用户提交的用户名、密码数据绑定到表单对象上,立刻执行校验逻辑(包括账号密码是否匹配的校验),如果校验失败,会把对应的错误信息写入表单对象的
errors属性;整个校验流程完全跑完之后,这个带着校验结果的表单对象才会被传给模板。
- 如果是用户第一次打开登录页的GET请求:视图会生成一个空的、没有绑定任何提交数据的表单对象,这个对象的
- 第三步:等后端所有逻辑全部处理完成,模板才会拿到包含表单对象的上下文,开始从上到下逐行渲染HTML:这时候先判断
form.errors是否有内容,有就显示错误提示,之后再渲染表单元素。
也就是说,{% if form.errors %}写在表单标签前面还是后面,都不会影响错误判断的结果——模板渲染时表单校验早就结束了,把错误提示放在表单前面是通用写法,目的是让用户进入页面后第一眼就能看到登录失败的提示,不用翻找表单下方的内容。
对应模板代码
{% extends 'learning_logs/base.html' %} {% block content %} {% if form.errors %} <p>Your username and password didn't match. Please try again.</p> {% endif %} <form method = "post" action="{% url 'login' %}"> {% csrf_token %} {{ form.as_p }} <button name = "submit">log in</button> <input type="hidden" name="next" value="{% url 'learning_logs:index' %}" /> </form> {% endblock content %}
内容的提问来源于stack exchange,提问作者szhang04
相关产品推荐
相关产品推荐

