使用django有一个好处就是有各种各样的框架可以拿来直接使用。相比flask,django自带的框架确实要多很多。比如这一章就要介绍的用户登录。Django拥有一个内置的认证(authentication)框架用来操作用户认证(authentication),会话(sessions),权限(permissions)以及用户组。这个认证(authentication)系统包含了一些普通用户的操作视图(views),例如:登录,登出,修改密码以及重置密码

这个认证(authentication)框架位于django.contrib.auth,被其他Django的contrib包调用,我们在之前的blog引用中使用这个认证(authentication)框架并为blog创建了一个超级用户来管理站点。

我们在创建应用的时候,认证框架已经包含了,在settings.py中的MIDDLEWARE。

MIDDLEWARE = [

'django.middleware.security.SecurityMiddleware',

'django.contrib.sessions.middleware.SessionMiddleware',

'django.middleware.locale.LocaleMiddleware',

'django.middleware.common.CommonMiddleware',

'django.middleware.csrf.CsrfViewMiddleware',

'django.contrib.auth.middleware.AuthenticationMiddleware',

'django.contrib.messages.middleware.MessageMiddleware',

'django.middleware.clickjacking.XFrameOptionsMiddleware',

]

AuthenticationMiddleware:使用会话(sessions)将用户和请求(requests)进行关联

SessionMiddleware:通过请求(requests)操作当前会话(sessions)

这个认证(authentication)系统还包含了以下模型(models):

User:一个包含了基础字段的用户模型(model);这个模型(model)的主要字段有:username, password, email, first_name, last_name, is_active。

Group:一个组模型(model)用来分类用户

Permission:执行特定操作的标识

下面我们就要来创建一个登录的视图。通过执行以下的操作来登录用户

1 通过提交的表单获取username和password

2 将得到的用户名和密码和存储在数据库中的进行认证

3 检查用户是否存在

4 登录用户到网站并且开始一个认证和会话

首先创建一个登录表单,在form.py中添加如下代码:

class LoginForm(forms.Form):

username=forms.CharField()

password=forms.CharField(widget=forms.PasswordInput)

forms.PasswordInput是在密码输入的HTML界面进行渲染的。接着在views.py中添加登录处理的代码

def user_login(request):

if request.method == 'POST':

form=LoginForm(request.POST)

if form.is_valid():

cd=form.cleaned_data

user=authenticate(username=cd['username'],password=cd['password'])

if user is not None:

if user.is_active:

login(request,user)

return HttpResponse(u'登录成功')

else:

return HttpResponse(u'登录失败')

else:

return HttpResponse(u'非法登录,请注册用户')

else:

form=LoginForm()

return render(request,'blog/login.html',{'form':form})

1 通过使用form=LoginForm(request.POST)得到提交的实例化表单

2 form.is_valid()检查这个表单是否正确,如果正确,通过form.cleaned_data

取出登录的用户名和密码

3 如果用户是有效的,通过user=authenticate(username=cd['username'],password=cd['password'])

对获取到的用户名和密码进行认证

4 如果用户可用,则用login(request,user)方法集合用户到会话中然后返回一条成功的消息

接下来就是创建url了。在mysite的urls.py中添加url(r'^account/',include('blog.urls')),

urlpatterns = [

url(r'^admin/', admin.site.urls),

url(r'^blog/',include('blog.urls',namespace='blog',app_name='blog')),

url(r'^test/$',views.test),

url(r'^account/',include('blog.urls')),

]

在blog应用下的urls.py中添加url(r'^login/$',views.user_login)

urlpatterns = [

# post views

url(r'^$', views.post_list_page, name='post_list'),

url(r'^(?P<post_id>\d+)/share/$',views.post_share,name='post_share'),

url(r'^(?P<post_id>\d+)/comment/$',views.post_comment,name='post_comment'),

url(r'^test/$',views.test),

url(r'^login/$',views.user_login)

]

最后来看我们的登录模板,在templates/blog下新建一个login.html

{% extends "base.html" %}

{% block title %}登录{% endblock %}

{% block content %}

<h1>用户登录</h1>

<p>请输入用户名和密码:</p>

<form action="." method="post">

{{ form.as_p }}

{% csrf_token %}

<p><input type="submit" value="Log-in"></p>

</form>

{% endblock %}

现在视图,url,模板都已经具备了,下面我们就是要创建一个真实的用户了。运行服务器进入admin界面进行用户名注册:用超级用户名进入后在Users点击add

输入用户名和帐号

权限设置

这里注意一点,如果忘记了普通用户的用户名和密码,可以登录超级用户帐号进去修改,但是如果连超级用户的密码也忘记了,可以通过如下的方式来修改:

在pycharm中进入Python console

输入如下代码操作用户数据库:

from django.contrib.auth.models import User

user=User.objects.get(username='用户名')

user.set_password('密码‘)

user.save()

下面我们就来开始登录,在浏览器中输入:http://127.0.0.1:8000/account/login/

得到如下的界面

输入用户名和密码后提示登录成功。

django还提供以下视图(views)来处理认证(authentication):

  • login:操作表单(form)中的登录然后登录一个用户
  • logout:登出一个用户
  • logout_then_login:登出一个用户然后重定向这个用户到登录页面

Django提供以下视图(views)来操作密码修改:

  • password_change:操作一个表单(form)来修改用户密码
  • password_change_done:当用户成功修改他的密码后提供一个成功提示页面

Django还包含了以下视图(views)允许用户重置他们的密码:

  • password_reset:允许用户重置他的密码。它会生成一条带有一个token的一次性使用链接然后发送到用户的邮箱中。
  • password_reset_done:告知用户已经发送了一封可以用来重置密码的邮件到他的邮箱中。
  • password_reset_complete:当用户重置完成他的密码后提供一个成功提示页面。

在blog应用中的urls.py中添加如下代码:

from django.contrib.auth.views import login

from django.contrib.auth.views import logout

from django.contrib.auth.views import logout_then_login

from django.contrib.auth.views import password_change

from django.contrib.auth.views import password_change_done

from django.contrib.auth.views import password_reset

from django.contrib.auth.views import password_reset_done

from django.contrib.auth.views import password_reset_confirm

from django.contrib.auth.views import password_reset_complete

然后在urlpatterns中添加对应的路径处理函数

urlpatterns = [

# post views

url(r'^$', views.post_list_page, name='post_list'),

url(r'^(?P<post_id>\d+)/share/$',views.post_share,name='post_share'),

url(r'^(?P<post_id>\d+)/comment/$',views.post_comment,name='post_comment'),

url(r'^test/$',views.test),

url(r'^login/$',login),

url(r'^logout/$', logout, name='logout'),

url(r'^logout-then-login/$', logout_then_login, name='logout_then_login'),

url(r'^password-change/$', password_change, name='password_change'),

url(r'^password-change/done/$', password_change_done, name='password_change_done'),

url(r'^password-reset/$',

password_reset,

name='password_reset'),

url(r'^password-reset/done/$',

password_reset_done,

name='password_reset_done'),

url(r'^password-reset/confirm/(?P<uidb64>[-\w]+)/(?P<token>[-\w]+)/$',

password_reset_confirm,

name='password_reset_confirm'),

url(r'^password-reset/complete/$',

password_reset_complete,

name='password_reset_complete'),

]

比如输入http://127.0.0.1:8000/account/password-change/则会自动跳转到密码修改的界面:

那么现在我们来优化下我们的登陆功能,前面在登陆完成以后跳转到一个页面提示跳转成功。现在我们来优化下这个功能,登陆后跳转到登陆前的界面

首先在url中

我们将url(r'^login/$',views.user_login)替换成url(r'^login/$',login,name="login")

也就是我们使用django中的登陆认证模块,使用这种认证模块必须在templates目录下创建一个新的目录命名为registration。这个路径是Django认证(authentication)视图(view)期望你的认证(authentication)模块(template)默认的存放路径。如果没有这个路径的话会提示如下的错误:

在这个新目录中创建一个新的文件,命名为login.html,然后添加如下代码:

{% extends "blog/base.html" %}

{% block title %}Log-in{% endblock %}

{% block content %}

<h1>用户登录</h1>

{% if form.errors %}

<p>

用户或密码不匹配,请输入正确的用户名和密码.

</p>

{% else %}

<p>填入下面的信息登陆:</p>

{% endif %}

<div class="login-form">

<form action="{% url 'login' %}" method="post">

{{ form.as_p }}

{% csrf_token %}

<input type="hidden" name="next" value="{{ next }}" />

<p><input type="submit" value="Log-in"></p>

</form>

</div>

{% endblock %}

我们添加了一个隐藏的HTML<input>元素来提交叫做next的变量值。当你在请求(request)中传递一个next参数(举个例子:http://127.0.0.1:8000/account/login/?next=/account/),这个变量是登录视图(view)首个设置的参数。

next参数必须是一个URL。当这个参数被给予的时候,Django登录视图(view)将会在用户登录完成后重定向到给予的URL。也就是在登陆完成后URL将从http://127.0.0.1:8000/account/login/?next=/account/跳转到http://127.0.0.1:8000/account

在settings.py中添加如下配置。LOGIN_URL和LOGOUT_URL中

from django.core.urlresolvers import reverse_lazy

LOGIN_URL = reverse_lazy('login')

LOGOUT_URL = reverse_lazy('logout')

这些设置的意义:

LOGIN_URL:重定向用户登录的URL(例如:使用login_required装饰器(decorator))。

LOGOUT_URL:重定向用户登出的URL。

我们使用reverse_lazy()来通过它们的名字动态构建URL。reverse_lazy()方法就像reverse()所做的一样reverses URLs,但是你可以通过使用这种方式在你项目的URL配置被读取之前进行reverse URLs。

我们现在来测试下,在post_list_page中使用login_required进行修饰

@login_required

def post_list_page(request):

object_list = Post.objects.all()

paginator = Paginator(object_list, 1)  # 3 posts in each page

page = request.GET.get('page')

new_comment = None

注意:这里的使用方式比较灵活。我们也可以在login_required中进行登录跳转界面的设置,这里设置了的话那么在settings.py中就不用设置了LOGIN_URL

@login_required(login_url='/account/login')

def post_list_page(request):

object_list = Post.objects.all()

paginator = Paginator(object_list, 1)  # 3 posts in each page

page = request.GET.get('page')

new_comment = None

下面我来进行测试,在浏览器中输入http://127.0.0.1:8000/blog。由于没有登录所以自动会跳转到http://127.0.0.1:8000/account/login/?next=/blog/进行用户登陆。这里并且传递了next的参数

输入用户名和密码后重新回到了http://127.0.0.1:8000/blog的地址并且显示了博客内容

既然已经实现了登陆,那么下面来看下退出登陆。首先在registration中创建一个logged_out.html。注意这个名称必须是logged_out,否则在退出登录的时候会自动跳转到admin/logout也就是管理页面的登出界面。文件代码如下:

{% extends "blog/base.html" %}

{% block title %}Logged out{% endblock %}

{% block content %}

<h1>用户退出</h1>

<p>你已经退出登陆<a href="{% url "login" %}">重新登陆</a></p>

{% endblock %}

在我们的博客显示界面添加退出登陆的链接:

<span class="user">

{% if request.user.is_authenticated %}

你好 {{ request.user.first_name }},

<a href="{% url "logout" %}">退出</a>

{% endif %}

</span>

页面显示如下

点击退出跳转到退出登陆的界面。我们点击重新登陆

我们点击重新登陆并再次输入用户名和密码却提示出错:

原因在于,我们在点重新登陆的时候,页面跳转到http://127.0.0.1:8000/account/login/。请注意,这个URL并没有next参数,也就是说只是纯粹的一个登录界面,在login.html中由于无法获取到next参数的值因此无法回到退出前的界面。此时url变为http://127.0.0.1:8000/accounts/profile/。我们在url中并没有这个路由,因此报错

那么如何解决呢,方法是在settings.py中设置登陆后的跳转界面

LOGIN_REDIRECT_URL = reverse_lazy('list')

并且在应用的urls.py中添加了路由

url(r'^$',views.post_list_page,name='list'),

这样在重新登陆后,界面将跳转到list这个url。这样我们再重新登录的时候就不会有问题了

在django的模块中还有修改密码,重置密码等功能,用法都是差不多的。这里简单介绍下

修改密码:

registration/目录下添加一个新的文件命名为password_form.html。添加如下代码:

{% extends "/blog/base.html" %}{% block title %}Change you password{% endblock %}{% block content %}

<h1>Change you password</h1>

<p>Use the form below to change your password.</p>

<form action="." method="post">

{{ form.as_p }}

<p><input type="submit" value="Change"></p>

{% csrf_token %}

</form>{% endblock %}

在相同的目录下创建另一个文件,命名为password_change_done.html来显示密码修改成功,为它添加如下代码:

{% extends "blog/base.html" %}{% block title %}Password changed{% endblock %}{% block content %}

<h1>Password changed</h1>

<p>Your password has been successfully changed.</p>

{% endblock %}

Django之博客系统:用户登陆的更多相关文章

  1. 纯django开发博客系统

    企业级教程:纯django开发博客系统 1.视频教程 https://www.duanshuilu.com/ 2.教程文档 https://www.duanshuilu.com/ 0.课程简介1.简价 ...

  2. Django(博客系统):基于pycharm如何一个django工程下创建多个app

    背景:通常我们创建一个django系统时,为了把业务模块划分清楚往往会把一个独立的业务模块放到一个app中,如果多个独立的业务模块就会创建多个app,一般情况下为了更好的管理这些app,会把他们都存放 ...

  3. Django练习——博客系统小试

    在上一篇博客Todolist的基础上(http://blog.csdn.net/hcx25909/article/details/24251427),本周继续进行实践,这次我要搭建一个简单的博客系统. ...

  4. form表单使用(博客系统的登陆验证,注册)

    先从小的实例来看form的用法 登陆验证实例,来看form的常规用法 1. forms.py # 用于登陆验证验证 from django.core.validators import RegexVa ...

  5. 【django之博客系统开发】

    一.项目简介 使用django开发一套博客系统,参考博客园. 需求如下: 项目结构: 二.全部代码 from django.db import models # Create your models ...

  6. Django之博客系统搭建一

    前面已经介绍了django的各种用法,从这一章开始,将实际搭建一个blog系统. 首先我们需要设计blog的模型,在models.py中添加如下内容 # -*- coding: utf-8 -*- f ...

  7. Django之博客系统邮件分享博客

    在上一章中,我们创建了一个基础的博客应用,我们能在http://127.0.0.1:8000/blog/显示我们的博客.在这一章我们将尝试给博客系统添加一些高级的特性,比如通过email来分享帖子,添 ...

  8. Django之博客系统:增加评论

    3既然是博客,那肯定就有留言评论系统.在这一章就来建立一个评论系统. 1 创建一个模型来保存评论 2 创建一个表单来提交评论并且验证输入的数据 3 添加一个视图函数来处理表单和保存新的评论到数据库 4 ...

  9. Django之博客系统:自定义模板标签

    Django提供了很多内置的模板标签比如{% if %}或者{% block %}Django也允许你创建自己的模板标签(template tags)来执行自定义的动作.当你需要在你的模板中添加功能而 ...

随机推荐

  1. laravel 多个where的连接使用

    在查询的时候需要用到多个where条件来查询 1.直接多个where连接 ->where()->where() 2.把查询条件 放到where数组$where中 然后 ->where ...

  2. Spring Boot发布和调用RESTful web service

    Spring Boot可以非常简单的发布和调用RESTful web service,下面参考官方指导体验一下 1.首先访问 http://start.spring.io/ 生成Spring Boot ...

  3. 机器学习:SVM(目标函数推导:Hard Margin SVM、Soft Margin SVM)

    一.Hard Margin SVM SVM 的思想,最终用数学表达出来,就是在优化一个有条件的目标函数: 此为 Hard Margin SVM,一切的前提都是样本类型线性可分: 1)思想 SVM 算法 ...

  4. WINDOWS 7下的记事本程序目录

    这是win7的目录    系统所在分区:\Windows\system32\notepad.exe

  5. 装饰器api

    import hashlib import time from django.http import HttpResponse key="qwrwertyuiop" visited ...

  6. python pdb 基础调试

    当手边没有IDE,面对着python调试犯愁时,你就可以参考下本文:(pdb 命令调试) 参考:http://docs.python.org/library/pdb.html 和 (pdb)help ...

  7. JVM知识点总览

    jvm 总体梳理 jvm体系总体分四大块: 类的加载机制 jvm内存结构 GC算法 垃圾回收 GC分析 命令调优 当然这些知识点在之前的文章中都有详细的介绍,这里只做主干的梳理 这里画了一个思维导图, ...

  8. Linux基础命令-文件与目录

    Linux基础命令-文件与目录 参考:<鸟哥linux私房菜>五-七章,17/12/5复习,18/01/15复习 文件权限 rwx421:用户,用户组,其他 umask查看默认权限:000 ...

  9. SpringBoot07 异常枚举、自定义异常、统一的全局异常处理

    1 异常编号和提示信息统一管理 利用枚举来实现异常的统一管理 package cn.xiangxu.springboottest.enums; import lombok.Getter; /** * ...

  10. 使用R语言绘制图表

    #========================================================#wolf moose graph version 20170616.R###Data ...