2.3 用内置方法实现登录和退出
在Django中,凡是通用的功能,都尽可能提供了默认方法,不需要用户编写代码,只需调用即可实现。
下面学习Django内置的登录方法。在使用之前,要找到这个方法写在什么地方,并且要看看源码。用内置方法实现登录和退出的基本知识如下图所示。

2.3.1 内置的登录方法
先找到Django的安装位置,我的是在C:\Python35\Lib\site-packages,当然这也放着其他第三方的Python库。
进入到Django目录中,直接找到写有内置登录函数的文件,即C:\Python35\Lib\site-packages\django\contrib\auth里面的views.py文件。
注意:django1和django2使用的内置函数是不同的
django使用的内置函数是 auth_views.login
打开./account/urls.py文件,做如下代码编辑。
1 from django.urls import path 2 from .import views 3 from django.contrib.auth import views as auth_views #① 4 5 app_name = 'account' 6 urlpatterns = [ 7 # path('login/',views.user_login,name='user_login'), #自定义的登录 8 path('login/',auth_views.LoginView.as_view(template_name='account/login2.html'),name='user_login'), #django内置的登录 9 10 ]
语句①引入了刚才找到的Django内置视图文件,并且将其重新 命名为auth_views,然后在路由配置中,使用auth_view.LoginView调用该视图文件中的LoginView()函数。
刚才看到的LoginView()函数中规定了模板,即registration/login.html,我们已经将本项目的所有模板都转移到了项目目录中的./templates里面,所以需要在./templates/registration中建立login.html模板。
1 {% extends "base.html" %} 2 3 {% load staticfiles %} 4 5 {% block title %}Login{% endblock %} 6 7 {% block content %} 8 <div class="row text-center vertical-middle-sm"> 9 <h1>Login</h1> 10 <p>Input your username and password</p> 11 <form class="form-horizontal" action="{% url 'account:user_login' %}" method="post">{% csrf_token %} 12 <!--{{ form.as_p}}--> 13 <div class="form-group"> 14 <label for="{{form.username.id_for_label}}" class="col-md-5 control-label" 15 style="color:red"><span class="glyphicon glyphicon-user"></span>Username</label> 16 <div class="col-md-6 text-left">{{ form.username }}</div> 17 </div> 18 <div class="form-group"> 19 <label for="{{form.password.id_for_label}}" class="col-md-5 control-label" 20 style="color:blue"><span class="glyphicon glyphicon-floppy-open"></span>Password</label> 21 <div class="col-md-6 text-left">{{ form.password }}</div> 22 </div> 23 <input type="submit" class="btn btn-primary btn-lg" value="Login"> 24 </form> 25 </div> 26 {% endblock %}
这次修改的地方是语句②中的action="{% url 'account:user_login' %}",用具体的URL指明了数据的POST目标。
将Django服务启动,在浏览器的地址栏输入http://127.0.0.1:8000/account/login/
要找原因,必须要看一下Django内置的LoginView()函数,在它的参数中有一项redirect_field_name=REDIRECT_FIELD_NAME,这就是登录后重定向的设置,上述跳转的地址,就是这个重定向设置的默认值,要想改变重定向的值,需要在.testsite/settings.py文件中设置LOGIN_REDIRECT_URL的值,在文件中添加此配置(可以放在最后)。
1 LOGIN_REDIRECT_URL = '/blog/'
这行代码的含义是登录后重定向到http://localhost:8000/blog/页面,当然可以设定为任何一个可以访问的地址作为重定向目标地址。
再次登录,发现登录成功之后神奇地转到了指定页面。
前面LoginView()函数设置了默认的模板路径,现在要修改一致,则要编辑./account/urls.py文件,代码如下:
1 from django.urls import path 2 from .import views 3 from django.contrib.auth import views as auth_views 4 5 app_name = 'account' 6 urlpatterns = [ 7 # path('login/',views.user_login,name='user_login'), #自定义的登录 8 # path('login/',auth_views.LoginView,name='user_login'), 9 path('login/',auth_views.LoginView.as_view(template_name='registration/login.html'),name='user_login'), #django内置的登录 #③ 10 11 ]
为了进行对比,原来的URL不变,新增加一个URL配置语句③,以一个字典类型,向默认的auth_views.LoginViews函数对象传template_name的值,account/login.html就是此前已经写好的登录模板文件。
保存后访问http://127.0.0.1:8000/account/login/,登录界面展现于眼前。

2.3.2 判断用户是否登录
在模板中,根据用户是否登录进行不同的显示,修改./templates/header.html模板,使LOGIN所在的位置根据用户登录状态显示不同的内容。如果用户已经登录,则显示用户名和Logout字样;如果用户尚未登录,则显示LOGIN字样,并做超链接到登录界面。
1 {% load staticfiles %} 2 <div class="container"> 3 <nav class="navbar navbar-default" role="navigation"> 4 <div class="navbar-header"> 5 <a class="navbar-brand" href="http://www.itdiffer.com"><img src="{%static '/images/logo.png'%}" 6 width="100px"></a> 7 </div> 8 <div> 9 <ul class="nav navbar-nav" role="navigation"> 10 <li><a href="{% url 'blog:blog_title' %">BLOG</a> </li> 11 </ul> 12 <ul class="nav navbar-nav navbar-right" style="margin-right:10px"> 13 {% if user.is_authenticated %} #① 14 <li><a href="#">{{ user.username }}</a> </li> 15 <li><a href="#">Logout</a> </li> 16 {% else %} 17 <li><a href="{% url 'account:user_login' %}">LOGIN</a> </li> 18 {% endif %} 19 </ul> 20 </div> 21 </nav> 22 </div>
在模板中,语句①类似Python中的if语句,请注意观察这种模板语言的书写规则。在模板中可以通过request.user得到用户对象,user.is_authenticated则是返回用户登录的状态,已经登录返回True,否则返回False。这样在模板中就可以根据用户的状态显示不同的内容。
上述代码中Logout和用户名的超链接都留空了,后续会填补上。登录之后的导航条状态如下图所示。

显示了登录用户的用户名和Logout。所谓Logout,即为退出。
2.3.3 内置的退出方法
Django内置退出函数,与登录函数类似,首先配置URL。
编辑./account/urls.py文件,增加如下内容。
1 path('logout/',auth_views.LogoutView.as_view(template_name='registration/logged_out.html'),name='user_logout'),
此处配置好后,把./templates/header.html文件中针对Logout的超链接修改一下
1 <li><a href="{% url 'account:user_logout' %}">Logout</a> </li>
检查Django服务是否在运行,刷新页面。如果没有登录,则找一个用户名来登录。一切准备就绪,单击Logout按钮,该用户退出,并且打开如下图所示的页面。

这个页面是Django为退出函数定义好的界面,虽然很丑,但毕竟实现了退出。
的确是丑了点,因为使用的是./templates/registration/logged_out.html默认模板,可以重写这个模板文件,在./templates/account/中创建一个退出的模板文件,名为logout.html,代码如下:
1 {% extends "base.html" %} 2 3 {% block title %}Logout{% endblock %} 4 5 {% block content %} 6 <div class="row text-center vertical-middle-sm"> 7 <p>You have log out.</p> 8 <p>You can <a href="{% url 'account:user_login' %}">login</a> again</p> 9 </div> 10 {% endblock %}
修改./account/urls.py文件,如下
1 path('logout/',auth_views.LogoutView.as_view(template_name='account/logout.html'),name='user_logout'),
再从登录状态执行退出操作,效果如下图所示。

2.3.4 知识点
1、HttpRequest对象
当客户端向服务器发送请求时,Django会创建一个包含请求数据的HttpRequest对象,并以参数request传给视图函数,即参数request所引用的对象就是HttpRequest对象。HttpRequest对象有很多属性,下面列出几项(除session外的其他属性都应该被看做是只读的,并且下列各项属性区分大小写)
- path:返回一个字符串,表示请求页面的路径(不包括域名),例如“/blog/admin”。
- GET:返回类字典对象,包括所有的HTTP GET参数。
- POST:返回类字典对象,包括所有的HTTP POST参数。注意,不包括上传文件信息。
- REQUEST:返回类字典对象,包括所有POST和GET数据(先POST,后GET;在项目实践中,不推荐使用这个属性获得对象数据,使用GET、POST更清晰)
- FILES:返回类字典对象,包含所有的上传文件,每个键是<input type="file" name=""/>中name的值,每个值是一个python字典,该字典有以下三个键:①filename,上传文件的文件名;②content-type,上传文件的内容类型;③content,上传文件的原始内容。注意FILES只有在请求方式为POST并且表单包括enctype="multipart/ form-data"属性时才会有数据,否则FILES就是一个空的类似字典的对象。
- COOKIES:返回字典,包括所有的cookie键值对。
- META:返回字典,包含所有可能的HTTP头。
- user:返回django.contrib.auth.users.User对象,表示当前登录用户。如果当前没有用户登录,user被设置成django.contrib.auth.models.AnonymousUser的一个实例,可以用is_anonymous()来区分登录用户和未登录用户,例如,
if request.user.is_anonymous(): # Do something for anonymous users. else: # Do something for logged-in users.
·
- session:返回可读写的类字典对象,表示当前的session。
在一个HttpRequest对象中,GET和POST属性都是django.http.QueryDict的实例。QueryDict是一个类字典的对象,可以处理同一个键有多个值的情况。
2、HttpResponse对象
HttpResponse是视图向客户端返回的对象。典型的用法就是将页面的内容作为字符串传递给HttpResponse函数,例如(以下示例来自官方文档):

浙公网安备 33010602011771号