Django之博客系统:用户登陆

摘要:
使用django有一个好处就是有各种各样的框架可以拿来直接使用。相比flask,django自带的框架确实要多很多。Django拥有一个内置的认证框架用来操作用户认证,会话,权限以及用户组。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:使用会话将用户和请求进行关联SessionMiddleware:通过请求操作当前会话这个认证系统还包含了以下模型:User:一个包含了基础字段的用户模型;这个模型的主要字段有:username,password,email,first_name,last_name,is_active。

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

这个认证(authentication)框架位于django.contrib.auth,被其他Djangocontrib包调用,我们在之前的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)的主要字段有:usernamepassword,email,first_name,last_name,is_active

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

Permission:执行特定操作的标识

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

1通过提交的表单获取usernamepassword

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

3检查用户是否存在

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

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

classLoginForm(forms.Form):

username=forms.CharField()

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

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

defuser_login(request):

ifrequest.method=='POST':

form=LoginForm(request.POST)

ifform.is_valid():

cd=form.cleaned_data

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

ifuserisnotNone:

ifuser.is_active:

login(request,user)

returnHttpResponse(u'登录成功')

else:

returnHttpResponse(u'登录失败')

else:

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

else:

form=LoginForm()

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

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

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

取出登录的用户名和密码

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

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

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

接下来就是创建url了。在mysiteurls.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=[

#postviews

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"%}

{%blocktitle%}登录{%endblock%}

{%blockcontent%}

<h1>用户登录</h1>

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

<formaction="."method="post">

{{form.as_p}}

{%csrf_token%}

<p><inputtype="submit"value="Log-in"></p>

</form>

{%endblock%}

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

Django之博客系统:用户登陆第1张

输入用户名和帐号

Django之博客系统:用户登陆第2张

权限设置

Django之博客系统:用户登陆第3张

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

pycharm中进入Pythonconsole

Django之博客系统:用户登陆第4张

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

fromdjango.contrib.auth.modelsimportUser

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

user.set_password('密码‘)

user.save()

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

得到如下的界面

Django之博客系统:用户登陆第5张

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

Django之博客系统:用户登陆第6张

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中添加如下代码:

fromdjango.contrib.auth.viewsimportlogin

fromdjango.contrib.auth.viewsimportlogout

fromdjango.contrib.auth.viewsimportlogout_then_login

fromdjango.contrib.auth.viewsimportpassword_change

fromdjango.contrib.auth.viewsimportpassword_change_done

fromdjango.contrib.auth.viewsimportpassword_reset

fromdjango.contrib.auth.viewsimportpassword_reset_done

fromdjango.contrib.auth.viewsimportpassword_reset_confirm

fromdjango.contrib.auth.viewsimportpassword_reset_complete

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

urlpatterns=[

#postviews

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/则会自动跳转到密码修改的界面:

Django之博客系统:用户登陆第7张

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

首先在url

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

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

Django之博客系统:用户登陆第8张

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

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

{%blocktitle%}Log-in{%endblock%}

{%blockcontent%}

<h1>用户登录</h1>

{%ifform.errors%}

<p>

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

</p>

{%else%}

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

{%endif%}

<divclass="login-form">

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

{{form.as_p}}

{%csrf_token%}

<inputtype="hidden"name="next"value="{{next}}"/>

<p><inputtype="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_URLLOGOUT_URL

fromdjango.core.urlresolversimportreverse_lazy

LOGIN_URL=reverse_lazy('login')

LOGOUT_URL=reverse_lazy('logout')

这些设置的意义:

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

LOGOUT_URL:重定向用户登出的URL

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

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

@login_required

defpost_list_page(request):

object_list=Post.objects.all()

paginator=Paginator(object_list,1)#3postsineachpage

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

new_comment=None

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

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

defpost_list_page(request):

object_list=Post.objects.all()

paginator=Paginator(object_list,1)#3postsineachpage

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的参数

Django之博客系统:用户登陆第9张

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

Django之博客系统:用户登陆第10张

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

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

{%blocktitle%}Loggedout{%endblock%}

{%blockcontent%}

<h1>用户退出</h1>

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

{%endblock%}

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

<spanclass="user">

{%ifrequest.user.is_authenticated%}

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

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

{%endif%}

</span>

页面显示如下

Django之博客系统:用户登陆第11张

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

Django之博客系统:用户登陆第12张

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

Django之博客系统:用户登陆第13张

原因在于,我们在点重新登陆的时候,页面跳转到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"%}{%blocktitle%}Changeyoupassword{%endblock%}{%blockcontent%}

<h1>Changeyoupassword</h1>

<p>Usetheformbelowtochangeyourpassword.</p>

<formaction="."method="post">

{{form.as_p}}

<p><inputtype="submit"value="Change"></p>

{%csrf_token%}

</form>{%endblock%}

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

{%extends"blog/base.html"%}{%blocktitle%}Passwordchanged{%endblock%}{%blockcontent%}

<h1>Passwordchanged</h1>

<p>Yourpasswordhasbeensuccessfullychanged.</p>

{%endblock%}

免责声明:文章转载自《Django之博客系统:用户登陆》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇JSTL 标签库详细介绍资料股票投资步骤下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

Django中间件 及 form 实现用户登陆

Django中间件 及 form 实现用户登陆 Form 验证 密码调用md5 加密存储 form.add_error("字段名", "错误信息") 自定义错误信息 装饰器实现 用户认证 中间件实现 用户认证 中间件顾名思义,是介于request与response处理之间的一道处理过程,相对比较轻量级,并且在全局上改变django的输入与输出。因为...

Django中CSS加载background url('')问题

Django中CSS加载background url('')问题 在django中, 默认CSS中如果有 background url('images/a.jpg') 这类的属性,会被django当成URL来解析 这样会造成找不到该文件的问题。 所以为了解决这个问题,首先需要配置setting.py, 配置STATICFILES_DIRS STATIC...

异步任务分发模块Celery

Celery简介 Celery是一个功能完备即插即用的任务队列。它使得我们不需要考虑复杂的问题,使用非常简单。 celery适用异步处理问题,当遇到发送邮件、或者文件上传, 图像处理等等一些比较耗时的操作,我们可将其异步执行,这样用户不需要等待很久,提高用户体验。 celery的特点是: 简单,易于使用和维护,有丰富的文档。 高效,单个celery进程每...

使用Python读写Kafka

本篇会给出如何使用python来读写kafka, 包含生产者和消费者. 以下使用kafka-python客户端 生产者 爬虫大多时候作为消息的发送端, 在消息发出去后最好能记录消息被发送到了哪个分区, offset是多少, 这些记录在很多情况下可以帮助快速定位问题, 所以需要在send方法后加入callback函数, 包括成功和失败的处理 # -*- co...

[ PyQt入门教程 ] PyQt5基本控件使用:单选按钮、复选框、下拉框、文本框

本文主要介绍PyQt5界面最基本使用的单选按钮、复选框、下拉框三种控件的使用方法进行介绍。 1、RadioButton单选按钮/CheckBox复选框。需要知道如何判断单选按钮是否被选中。 2、ComboBox下拉框。需要知道如何对下拉框中的取值进行设置以及代码实现中如何获取用户选中的值。 带着这些问题下面开始介绍这RadioButton单选按钮、Chec...

AngularJS中的表单验证

AngularJS中的表单验证 AngularJS自带了很多验证,什么必填,最大长度,最小长度...,这里记录几个有用的正则式验证 Note that novalidate is used to disable browser's native form validation. 用来禁用H5的原生验证. 1.使用angularjs的表单验证 正则式验证 只...