你应该注意到了一点,当你去新建、修改和删除文章的时候并不需要登录,这样的话任何浏览网站的用户都能随时修改和删除我的文章。这个可不是我想要的!

编辑和删除的认证

我们需要保护post_new, post_edit和post_publish这三个视图,只有登录用户才有权去执行。 django为我们提供了很好的帮助类,其实就是利用了python中的decorators技术。 django中认证的装饰器位于模块django.contrib.auth.decorators中,名称叫login_required。

编辑blog/views.py文件,在import部分添加如下的导入语句:

1
from django.contrib.auth.decorators import login_required

然后在post_new, post_edit和post_publish这三个函数上添加@login_required, 类似下面

1
2
3
@login_required
def post_new(request):
[...]

好的,现在你再去访问下http://localhost:8000/post/new/,看看有啥变化。

注:如果你仍然能正常进入新建页面,那可能是你之前在admin界面登陆过。 那么你需要先退出,访问http://localhost:8000/admin/logout/可以退出,然后你再看下效果。

我刚刚添加的@login_required装饰器检测到你尚未登陆的时候会重定向到login页面, 但是我现在还没有定义login的模板页面,所以这时候会是404错误页面。

用户登录

django在用户认证方面做得很好了,我们只需要去使用它就行。

在mysite/urls.py文件中,添加下面一行

1
url(r'^accounts/login/$', 'django.contrib.auth.views.login')

现在这个文件内容如下:

1
2
3
4
5
6
7
8
9
10
from django.conf.urls import patterns, include, url

from django.contrib import admin
admin.autodiscover() urlpatterns = patterns('',
url(r'^admin/', include(admin.site.urls)),
url(r'^accounts/login/$', 'django.contrib.auth.views.login'),
url(r'', include('blog.urls')),
)

然后我们再定义一个登陆页面,创建目录mysite/templates/registration, 并在里面新建模板文件login.html,内容如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
{% extends "mysite/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 'django.contrib.auth.views.login' %}">
{% csrf_token %}
<table>
<tr>
<td>{{ form.username.label_tag }}</td>
<td>{{ form.username }}</td>
</tr>
<tr>
<td>{{ form.password.label_tag }}</td>
<td>{{ form.password }}</td>
</tr>
</table> <input type="submit" value="login" />
<input type="hidden" name="next" value="{{ next }}" />
</form>
{% endblock %}

你可以看到我们仍然使用到了模板继承。这个时候可以定义一个mysite/templates/mysite/base.html, 把blog/templates/blog/base.html的内容复制给它即可。

不过我们需要在mysite/settings.py中再添加一个urls配置:

1
LOGIN_REDIRECT_URL = '/'

这样的话当用户直接访问login页面后登录成功会重定向到文章列表页面去。

改进显示

现在的确只有登录用户才能修改和删除文章,但是未登录用户却能看到这些按钮, 这个是很不好的体验。现在如果是未登录用户的话就把这些按钮给隐藏掉。

因此我们修改mysite/templates/mysite/base.html如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<body>
<div class="page-header">
{% if user.is_authenticated %}
<a href="{% url 'post_new' %}" class="top-menu"><span class="glyphicon glyphicon-plus"></span></a>
<a href="{% url 'post_draft_list' %}" class="top-menu"><span class="glyphicon glyphicon-edit"></span></a>
{% else %}
<a href="{% url 'django.contrib.auth.views.login' %}" class="top-menu"><span class="glyphicon glyphicon-lock"></span></a>
{% endif %}
<h1><a href="{% url 'blog.views.post_list' %}">Django Girls</a></h1>
</div>
<div class="content">
<div class="row">
<div class="col-md-8">
{% block content %}
{% endblock %}
</div>
</div>
</div>
</body>

然后修改blog/templates/blog/post_detail.html如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
{% extends 'blog/base.html' %}

{% block content %}
<div class="date">
{% if post.published_date %}
{{ post.published_date }}
{% else %}
{% if user.is_authenticated %}
<a class="btn btn-default" href="{% url 'blog.views.post_publish' pk=post.pk %}">Publish</a>
{% endif %}
{% endif %}
{% if user.is_authenticated %}
<a class="btn btn-default" href="{% url 'post_edit' pk=post.pk %}"><span class="glyphicon glyphicon-pencil"></span></a>
<a class="btn btn-default" href="{% url 'post_remove' pk=post.pk %}"><span class="glyphicon glyphicon-remove"></span></a>
{% endif %}
</div>
<h1>{{ post.title }}</h1>
<p>{{ post.text|linebreaks }}</p>
{% endblock %}

用户注销

当用户登录后显示欢迎语句,Hello ,然后后面跟一个logout链接。还是依靠django帮我们处理logout动作。

修改mysite/templates/mysite/base.html文件如下:

1
2
3
4
5
6
7
8
9
10
<div class="page-header">
{% if user.is_authenticated %}
<a href="{% url 'post_new' %}" class="top-menu"><span class="glyphicon glyphicon-plus"></span></a>
<a href="{% url 'post_draft_list' %}" class="top-menu"><span class="glyphicon glyphicon-edit"></span></a>
<p class="top-menu">Hello {{ user.username }}<small>&nbsp;<a href="{% url 'django.contrib.auth.views.logout' %}">Log out</a></p>
{% else %}
<a href="{% url 'django.contrib.auth.views.login' %}" class="top-menu"><span class="glyphicon glyphicon-lock"></span></a>
{% endif %}
<h1><a href="{% url 'blog.views.post_list' %}">Django Girls</a></h1>
</div>

很显然这时候logout肯定会报错。我们还得做些事情。

对于这方面的详细文档请参考:https://docs.djangoproject.com/en/1.9/topics/auth/default/

打开mysite/urls.py文件,添加一个logout配置:

1
2
3
4
5
6
7
8
9
10
11
from django.conf.urls import patterns, include, url

from django.contrib import admin
admin.autodiscover() urlpatterns = patterns('',
url(r'^admin/', include(admin.site.urls)),
url(r'^accounts/login/$', 'django.contrib.auth.views.login'),
url(r'^accounts/logout/$', 'django.contrib.auth.views.logout', {'next_page': '/'}),
url(r'', include('blog.urls')),
)

如果访问网站时出现模板找不到错误,那么你就在mysite/settings.py中添加如下配置:

1
2
3
4
5
# TEMPLATE_DIRS
TEMPLATE_DIRS = (
os.path.join(BASE_DIR, 'mysite/templates'),
os.path.join(BASE_DIR, 'blog/templates'),
)

好的,现在你已经可以达成如下的效果了:

  1. 需要一个用户名和密码登录系统
  2. 在添加/编辑/删除/发布文章的时候需要登录
  3. 也能注销

Django1.9开发博客(9)- 用户认证的更多相关文章

  1. Django1.7开发博客

    转自: http://www.pycoding.com/articles/category/django 基于最新的django1.7写的,通俗易懂,非常适合新手入门. 感谢博主! 参考教程: htt ...

  2. Django1.9开发博客(14)- 集成Xadmin

    xadmin是一个django的管理后台实现,使用了更加灵活的架构设计及Bootstrap UI框架, 目的是替换现有的admin,国人开发,有许多新的特性: 兼容 Django Admin 使用 B ...

  3. Django1.9开发博客(12)- i18n国际化

    国际化与本地化的目的为了能为各个不同的用户以他们最熟悉的语言和格式来显示网页. Django能完美支持文本翻译.日期时间和数字的格式化.时区. 另外,Django还有两点优势: 允许开发者和模板作者指 ...

  4. Django1.9开发博客(7)- 实现功能

    到目前为止我们已经完成了一个django应用的所有基础部分. 包括url配置.视图.模型和模板.接下来开始继续完善我们的博客系统了. 首先我们需要一个显示每篇文章的详细页面,对不? 文章详情 对于首页 ...

  5. Django1.9开发博客(11)- 富文本与代码高亮

    TinyMCE是一个轻量级的基于浏览器的所见即所得编辑器,支持目前流行的各种浏览器,由JavaScript写成. 功能配置灵活简单(两行代码就可以将编辑器嵌入网页中),支持AJAX.另一特点是加载速度 ...

  6. Django1.9开发博客(8)- 继续完善

    到现在为止我们已经完成的差不多了,并且基本的东西都已经学到了,是时候用起来了. 我们的博客还有很多功能需要完善,下面抛砖引玉新增几个功能,还有其他功能等你自己去发现和实现. 草稿箱 之前我们新建文章的 ...

  7. Django1.9开发博客(13)- redis缓存

    Redis 是一个高性能的key-value数据库.redis的出现, 很大程度补偿了memcached这类keyvalue存储的不足,在部分场合可以对关系数据库起到很好的补充作用. 它提供了Pyth ...

  8. Django1.9开发博客(10)- 全文搜索

    Django本身不提供全文检索的功能,但django-haystack为其提供了全文检索的框架. django-haystack能为Django提供whoosh,solr,Xapian和Elastic ...

  9. Django1.9开发博客(6)- 模板继承

    模板继承就是网站的多个页面可以共享同一个页面布局或者是页面的某几个部分的内容.通过这种方式你就需要在每个页面复制粘贴同样的代码了. 如果你想改变页面某个公共部分,你不需要每个页面的去修改,只需要修改一 ...

随机推荐

  1. Python开发【第六章】:Python面向对象

    编程范式 编程是程序员用特定的语法+数据结构+算法组成的代码来告诉计算机如何执行任务的过程,一个程序是程序员为了得到一个任务结果而编写的一组指令的集合,正所谓条条大路通罗马,实现一个任务的方式有很多种 ...

  2. RML Utilities for SQL Server

    很早以前有看到过关于使用RML Utilities工具分析SQL Trace(.trc)的文章,但一直没有具体实践.最近接管一台数据库服务器,跟踪出一批高消耗的语句,老大需要跟踪分析报表,罗列出过程( ...

  3. python Shapely 使用指南

    翻译:http://toblerity.org/shapely/manual.html 引入包 from shapely.geometry import Point from shapely.geom ...

  4. Simple JavaScript Inheritance--一个极简JS面向对象-类库

    面向对象 面向对象思想的几个重要特征(针对类的要求): 抽象-封装.信息隐藏(将内部实现的方法和数据隐藏, 定义开放的接口) 继承-子类可以使用父类的资源,并可以定制自己的资源, 资源包括方法和数据 ...

  5. java学习规划

    今天在网上看到一位大学生的java学习线路规划,觉得蛮适合我,就详细阅读了一下,规划路线应该适用于大部分学习java语言的人,贴出来与大家共勉. 在学习的过程中,不能急于去学习更多的知识,因为知识是无 ...

  6. react 评论列表插入评论数据 unshift

    // unshift 新增数据放到最上面 //插入 回复/发表 评论else if(action.type === INSERT_COMMENT ){ let content = action.tex ...

  7. JavaScript挑战复杂报表——1总述

    今天用自己写的库完成了一个40列填报报表的前后台调试,所花费的时间超过预期很多.遇到的坑有:ajax回调函数写错导致循环调用,没有考虑到java的request.getParameter()方法读入数 ...

  8. YII2.0--------这篇文章记录我学习YII2.0的过程吧,也可以让更多的人少走弯路

    1.情况:今天我从github上下载了一个项目,本以为直接丢到根目录运行就行了,但是不行. 解决办法:首先安装git,安装步骤这里不讲了,稍微讲一下配置环境变量.

  9. url传值错误

    ValueError at /add/ invalid literal for int() with base 10: ''6'' Request Method: GET Request URL: h ...

  10. Git错误non-fast-forward后的冲突解决

    Git错误non-fast-forward后的冲突解决当要push代码到git时,出现提示: error:failed to push some refs to ... Dealing with “n ...