django用户认证系统——登录4

 

 

用户已经能够在我们的网站注册了,注册就是为了登录,接下来我们为用户提供登录功能。和注册不同的是,Django 已经为我们写好了登录功能的全部代码,我们不必像之前处理注册流程那样费劲了。只需几分钟的简单配置,就可为用户提供登录功能。接下来就来看看如何使用内置的登录功能。

引入内置的 URL 模型

Django 内置的登录、修改密码、找回密码等视图函数对应的 URL 模式位于 django.contrib.auth.urls.py 中,首先在工程的 urls.py 文件里包含这些 URL 模式。打开 django_auth_example/ 目录下的 urls.py 文件,将 django.contrib.auth.urls.py 包含进来:

django_auth_example/urls.pyfrom django.conf.urls import url, include from django.contrib import admin urlpatterns = [ url(r'^admin/', admin.site.urls), url(r'^users/', include('users.urls')), # 将 auth 应用中的 urls 模块包含进来 url(r'^users/', include('django.contrib.auth.urls')), ] 

这将包含以下的 URL 模式:

^users/login/$ [name='login']
^users/logout/$ [name='logout']
^users/password_change/$ [name='password_change']
^users/password_change/done/$ [name='password_change_done']
^users/password_reset/$ [name='password_reset']
^users/password_reset/done/$ [name='password_reset_done']
^users/reset/(?P<uidb64>[0-9A-Za-z_\-]+)/(?P<token>[0-9A-Za-z]{1,13}-[0-9A-Za-z]{1,20})/$ [name='password_reset_confirm']
^users/reset/done/$ [name='password_reset_complete']

设置模板路径

默认的登录视图函数渲染的是 registration/login.html 模板,因此需要在 templates/ 目录下新建一个 registration 文件夹,再在 registration/ 目录下新建 login.html 模板文件。此时目录结构为:

django_auth_example/manage.pydjango_auth_example/__init__.pysettings.pyurls.pywsgi.pytemplates/users/register.htmlregistration/login.html

编写登录模板

登录模板的代码和注册模板的代码十分类似:

registration/login.html<!DOCTYPE html>
<html lang="zh-cn"> <head> <meta charset="utf-8"> <meta http-equiv="x-ua-compatible" content="ie=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no"> <title>登录</title> <link rel="stylesheet" href="https://unpkg.com/mobi.css/dist/mobi.min.css"> <style> .errorlist { color: red; } </style> </head> <body> <div class="flex-center"> <div class="container"> <div class="flex-center"> <div class="unit-1-2 unit-1-on-mobile"> <h3>登录</h3> <form class="form" action="{% url 'login' %}" method="post"> {% csrf_token %} {{ form.non_field_errors }} {% for field in form %} {{ field.label_tag }} {{ field }} {{ field.errors }} {% if field.help_text %} <p class="help text-small text-muted">{{ field.help_text|safe }}</p> {% endif %} {% endfor %} <button type="submit" class="btn btn-primary btn-block">登录</button> </form> <div class="flex-left top-gap text-small"> <div class="unit-2-3"><span>没有账号?<a href="{% url 'users:register' %}">立即注册</a></span></div> <div class="unit-1-3 flex-right"><span><a href="reset_password.html">忘记密码?</a></span></div> </div> </div> </div> </div> </div> </body> </html> 

为了登录页面的美观我引入了 mobi.css 提供样式支持,其它代码请忽略,我们只关注表单部分的代码。

<form class="form" action="{% url 'login' %}" method="post"> {% csrf_token %} {{ form.non_field_errors }} {% for field in form %} {{ field.label_tag }} {{ field }} {{ field.errors }} {% if field.help_text %} <p class="help text-small text-muted">{{ field.help_text|safe }}</p> {% endif %} {% endfor %} <button type="submit" class="btn btn-primary btn-block">登录</button> </form> 

循环表单字段、渲染控件、渲染帮助信息等在注册表单部分已经讲过,登录表单中只引入了一个新的东西:{{ form.non_field_errors }},这显示的同样是表单错误,但是显示的表单错误是和具体的某个表单字段无关的。相对 {{ field.errors }},这个则显示的是具体某个字段的错误。比如对于字段 username,如果用户输入的 username 不符合要求,比如太长了或者太短了,表单会在 username 下方渲染这个错误。但有些表单错误不和任何具体的字段相关,比如用户输入的用户名和密码无法通过验证,这可能是用户输入的用户名不存在,也可能是用户输入的密码错误,因此这个错误信息将通过 {{ form.non_field_errors }} 渲染。

注意:你可能觉得用户名不存在错误和 username 字段有关,密码错误和 password 字段有关。但是在现代的用户认证系统中,我们不为用户提供这么详细的信息,只是笼统地告知用户名不存在或者密码错误。这能提高一些用户账户的安全性。

此外登录表单的 action 属性的值是 {% url 'login' %},即 auth 应用下的 login 视图函数对应的 URL,用户提交的表单数据将提交给这个 URL,Django 调用 login 视图函数来处理。

不要忘了加 {% csrf_token %} 模板标签。

现在打开开发服务器,在浏览器输入 http://127.0.0.1:8000/users/login/,你将看到一个用户登陆表单。

用户登陆表单

故意使用一个不存在的账户登录,或者故意输错密码,你将看到表单渲染的非字段相关的错误。

登录错误信息

如果用户登录成功,你会发现跳转到了 http://127.0.0.1:8000/accounts/profile/ 页面。由于我们没有写任何视图函数处理这个 URL,所以看到一个 404 错误。不过没有关系,我们目前只关注用户是否已经登录。

如何在模板中判断用户是否已经登录

在模板中判断用户是否已经登录非常简单,使用 {% if user.is_authenticated %} 条件判断即可。借此机会,我们来处理一下网站首页。

在 user/views.py 写一个首页视图函数:

user/views.py def index(request): return render(request, 'index.html') 

为这个视图函数配置 URL 模式,在 django_auth_example/urls.py 进行配置:

from django.conf.urls import url, include from django.contrib import admin from users import views urlpatterns = [ url(r'^admin/', admin.site.urls), # 别忘记在顶部引入 include 函数 url(r'^users/', include('users.urls')), url(r'^users/', include('django.contrib.auth.urls')), # 别忘记在顶部引入 views 模块 url(r'^$', views.index, name='index') ] 

注意:直接在项目的 urls.py 中配置 URL 是不推荐的,应该在应用的 urls.py 下进行配置,然后在项目的 urls.py 中通过 include 函数包含。不过这里作为示例情况特殊,所以姑且这样做。

由于视图渲染了 index.html 文件,因此在 templates/ 目录下建一个 index.html 模板文件(注意我们没有把它放在 users/ 下,也没放在 registration/ 下)。然后写上下面的代码:

templates/index.html<!DOCTYPE html>
<html lang="zh-cn"> <head> <meta charset="utf-8"> <meta http-equiv="x-ua-compatible" content="ie=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no"> <title>首页</title> <link rel="stylesheet" href="https://unpkg.com/mobi.css/dist/mobi.min.css"> </head> <body> <div class="flex-center"> <div class="container"> <div> <h1 class="logo"><a href="{% url 'index' %}">Django Auth Example</a></h1> {% if user.is_authenticated %} <p>你已登录,欢迎你:<a href="#">{{ user.username }}</a></p> {% else %} <p>你还没有登录,请 <button class="btn btn-default"><a href="{% url 'login' %}">登录</a></button> 或者 <button class="btn btn-default"><a href="{% url 'users:register' %}">注册</a></button> </p> {% endif %} </div> </div> </div> </body> </html> 

为了页面的美观,我引入了 mobi.css 提供样式支持。其它代码请忽略,重点只关注用户登录验证部分:

{% if user.is_authenticated %}<p>你已登录,欢迎你:<a href="#">{{ user.username }}</a></p> {% else %} <p>你还没有登录,请 <button class="btn btn-default"><a href="{% url 'login' %}">登录</a></button> 或者 <button class="btn btn-default"><a href="{% url 'users:register' %}">注册</a></button> </p> {% endif %} 

user.is_authenticated 当用户已经登录时返回 True,否则返回 False。所以已登录的用户将看到欢迎页面,否则将看到登录注册按钮。

你也许奇怪我们在 index 视图中并没有传递 user 模板变量给 index.html,为什么可以在模板中引用 user 呢?这是因为 Django 的 auth 应用为我们设置了模板常量,所以在任何模板中都可以引用 {{ user }}。此外,我们之前提过的 django.contrib.auth.middleware.AuthenticationMiddleware 为所有的请求 request 绑定了一个 user 属性。所以在模板中引用 {{ user }} 和 {{ request.user }} 是等价。

OK 了!不过目前为止,如果你已经登录过了,想要看看未登录的效果会变得比较困难,因为我们还无法注销登录。下面就来给网站添加注销登录的功能吧!

转载于:https://www.cnblogs.com/AmilyWilly/p/8469859.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/369585.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

php缓存类,PHP缓存类

// ----------------------------------------------------------------------// |缓存类// ----------------------------------------------------------------------// | Author: justmepzy(justmepzygmail.com)// -------------------------------------------------------…

双向@OneToMany / @ManyToOne关联

编程的目标之一是代表现实世界中的模型。 通常&#xff0c;应用程序需要对实体之间的某些关系进行建模。 在上一篇有关Hibernate关联的文章中&#xff0c;我描述了建立“一对一”关系的规则。 今天&#xff0c;我将向您展示如何设置双向的“ 一对多 ”和“ 多对一 ”关联。 这个…

web前端黑客技术揭秘 6.漏洞挖掘

6.1  普通XSS漏洞自动化挖掘思路 6.1.1  URL上的玄机 6.1.2  HTML中的玄机 2.HTML标签之内 6.1.3  请求中的玄机 6.1.4  关于存储型XSS挖掘 6.2.1  HTML与JavaScript自解码机制 <input type"button" id"exec_btn" value"exec" on…

Webpack基础使用

目录 一.什么是Webpack 二.为什么要使用Webpack 三.Webpack的使用 1.下载yarn包管理器 2.Webpack的安装 3.Webpack的简单使用 4.效果 四.Webpack打包流程 一.什么是Webpack Webpack是一个静态模块打包工具 二.为什么要使用Webpack 在开发中&#xff0c;我们常常会遇到…

CSS3及JS媒体查询教程

CSS3媒体查询&#xff1a; 语法&#xff1a; <media_query_list>&#xff1a;<media_query>[,<media_query>] <media_query>&#xff1a;only|not <mediaType> and <expression>[ and <expression>] <expression>&#xff1a;…

php mongodb

// 欄位字串為$querys array("name">"shian");// 數值等於多少$querys array("number">7);// 數值大於多少$querys array("number">array($gt > 5));// 數值大於等於多少$querys array("number">array($…

阿帕奇骆驼遇见Redis

键值商店的兰博基尼 Camel是最好的面包集成框架&#xff0c;在本文中&#xff0c;我将向您展示如何通过利用另一个出色的项目Redis使它更加强大。 Camel 2.11即将发布&#xff0c;具有许多新功能&#xff0c;错误修复和组件。 这些新组件中的几个是我创作的&#xff0c; red…

php 数字加逗号,php数字满三位添加一逗号

//数字满三位添加一逗号&#xff1a;$s_money1 1000000;$s_money2 number_format($s_money1);echo $s_money1;//1000000echo "";echo $s_money2;//1,000,000PHP number_format() 函数number_format() 函数通过千位分组来格式化数字。注释&#xff1a;该函数支持一个…

HTML 教程- (HTML5 标准)摘抄笔记

HTML 教程- (HTML5 标准) 教程网址&#xff1a;http://www.runoob.com/html/html-tutorial.html http://blog.csdn.net/ljfbest/article/details/6700148 HTML版本 从初期的网络诞生后&#xff0c;已经出现了许多HTML版本: 版本发布时间HTML1991HTML 1993HTML 2.01995HTML 3…

spring 隔离级别 测试代码

Controller RequestMapping("/test") Api(value "测试", description "测试") public class TestController {Autowiredprivate TestService testService;RequestMapping(value "listForDirtyRead", method RequestMethod.GET)Res…

他人的一些2017年度总结

闭环思维&#xff1a;自己在做工作的时候&#xff0c;以及在做事情的时候&#xff0c;逐渐养成了闭环思考模式。一个新的东西&#xff0c;一个新的方案&#xff0c;从场景开始梳理&#xff0c;一步步的梳理流程和方案&#xff0c;然后到最终的方案落地&#xff0c;所有的一套流…

Java EE CDI ConversationScoped示例

在本教程中&#xff0c;我们将向您展示如何在Web应用程序中创建和使用ConversationScoped Bean。 在CDI中&#xff0c;bean是定义应用程序状态和/或逻辑的上下文对象的源。 如果容器可以根据CDI规范中定义的生命周期上下文模型来管理其实例的生命周期&#xff0c;则Java EE组件…

block与inline,inline和inline-block,块级和行内元素,行内替换和行内非替换元素

block:块级元素默认display属性为block&#xff1b;无论块内内容有多少&#xff0c;总是占满一行&#xff1b; inline:行内元素默认display属性为inline&#xff1b;只占据块内的内容的大小&#xff0c;不会占满一整行&#xff1b; inline-block:将行内元素的display属性改为…

mybatis深入理解之 # 与 $ 区别以及 sql 预编译

mybatis 中使用 sqlMap 进行 sql 查询时&#xff0c;经常需要动态传递参数&#xff0c;例如我们需要根据用户的姓名来筛选用户时&#xff0c;sql 如下&#xff1a; select * from user where name "ruhua"; 上述 sql 中&#xff0c;我们希望 name 后的参数 "ru…

Git 中文教程

以下内容转载自&#xff1a;http://www.open-open.com/lib/view/open1328928294702.html Git是一个分布式的版本控制工具&#xff0c;本篇文章从介绍Git开始&#xff0c;重点 在于介绍Git的基本命令和使用技巧&#xff0c;让你尝试使用Git的同时&#xff0c;体验到原来一个版本…

php markdown的转化函数,markdown公式转为知乎格式

在知乎中写技术类文章&#xff0c;经常会用到markdown知乎文章可以导入markdown格式&#xff0c;但是不支持Latex公式。知乎大神提供了替代方案&#xff1a; https://zhuanlan.zhihu.com/p/69142198为实现自动化&#xff0c;用python将其简易实现&#xff0c;代码如下&#xff…

Java EE CDI Producer方法教程

这是CDI Producer方法的教程。 在CDI中&#xff0c;生产者方法生成一个可以注入的对象。 当我们要注入本身不是bean的对象&#xff0c;要注入的对象的具体类型在运行时可能有所不同&#xff0c;或者当对象需要一些bean构造函数不执行的自定义初始化时&#xff0c;可以使用生产者…

CSS的常用属性(二)

盒子模型之边框 border-(top/bottom/left/right)-style: solid 边框的风格 如(solid 实线&#xff0c;dotted 点线&#xff0c;dashed 虚线) border-top-color: #aaa 边框颜色 border-top-width: 20px 边框粗细 边框四个方向连写&#xff1a; 如 border-color: #000 边框属…

牛客网Java刷题知识点之方法覆盖(方法重写)和方法重载的区别

不多说&#xff0c;直接上干货&#xff01; https://www.nowcoder.com/ta/review-java/review?query&asctrue&order&page6 方法重写的原则&#xff1a; 重写方法的方法名称、参数列表必须与原方法的相同&#xff0c;返回类型可以相同也可以是原类型的子类型(从Jav…

7-26 Windows消息队列

7-26 Windows消息队列&#xff08;25 分&#xff09; 消息队列是Windows系统的基础。对于每个进程&#xff0c;系统维护一个消息队列。如果在进程中有特定事件发生&#xff0c;如点击鼠标、文字改变等&#xff0c;系统将把这个消息加到队列当中。同时&#xff0c;如果队列不是空…