# Django Step by Step (五)
## 1 引言
其实本教程以展示基本概念为已任,对于一些高级的话题我也在不停地学习中,希望能有所展示。让我们一起学习吧。
在了解了基本的 Django 开发的过程及 Django 的一些基本特性之后,越来越多的东西在等着我们。现在我们就学习一下 session 吧。 session 可以翻译为“会话”,做过web的可能都知道。它就是为了实现页面间的数据交换而产生的东西,一般有一个 session_id ,它会保存在浏览器的 cookie 中,因此如果你的浏览器禁止了 cookie ,下面的试验是做不了的。
在 Django 中的 session 也非常简单,它就存在于 `request` 对象的 `session` 属性中。你可以把它看成一个字典就可以了。
下面我们做一个非常简单的功能:首先当用户进入某个页面,这个页面会显示一个登录页面,上面有一个文本框用来输入用户名,还有一个提交按钮用来提交数据。当用户输入用户名,然后点提交,则显示显示用户已经登录,并且打印出用户的姓名来,同时还提供一个“注销”按钮。然后如果用户再次进入这个页面,则显示同登录成功后的页面。如果点击注销则重新进入未登录的页面。
## 2 在newtest下创建 login.py
```python
from django.http import HttpResponseRedirect
from django.shortcuts import render_to_response
from django.views.decorators.csrf import csrf_exempt
@csrf_exempt
def login(request):
username = request.POST.get('username', None)
if username:
request.session['username'] = username
username = request.session.get('username', None)
if username:
return render_to_response('login.html', {'username':username})
else:
return render_to_response('login.html')
@csrf_exempt
def logout(request):
try:
del request.session['username']
except KeyError:
pass
return HttpResponseRedirect("/login/")
```
有些复杂了吗?没关系,让我解释一下。这里有两个方法: `login()` 和 `logout()` 。 `login()` 用来提供初始页面、处理提供数据和判断用户是否登录。而 `logout()` 只是用来从 session 中删除用户名,同时将页面重定向到 login 画面。这里我仍然使用了模板,并且根据传入不同的字典来控制模板的生成。是的,因为 Django 的模块支持条件判断,所以可以做到。
在 `login()` 中的判断逻辑是:
* 先从 POST 中取 `username` (这样 `username` 需要由模板的 form 来提供),如果存在则加入到 session 中去。加入 session 很简单,就是一个字典的 Key 赋值。
* 然后再从 session 中取 `username` ,有两种可能:一种是上一步实现的。还有一种可能是直接从以前的 session 中取出来的,它不是新产生的。而这里并没有细分这两种情况。因此这个判断其实对应两种页面请求的处理:一种是提交了用户姓名,而另一种则是处理完用户提交姓名之后,用户再次进入的情况。而用户再次进入时,由于我们在前面已经将他的名字保存在 session 里面了,因此可以直接取出来。如果 session 中存在,则表示用户已经登录过,则输出 `login.html` 模板,同时传入了 `username` 字典值。而如果 session 中不存在,说明用户从来没有登录过,则输出 `login.html` 模板,这次不带值。
因此对于同一个 `login.htm` 模板传入的不同值,后面我们会看到模板是如何区分的。
在 `logout()` 中很简单。先试着删除 session ,然后重定向页面到 login 页面。这里使用了 `HttpResponseRedirect` 方法,它是从以前我们看到的 `HttpResponse` 派生来的子类。更多的派生子类和关于 response 的内容要参考 Request and response objects 文档。
## 3 创建 templates/login.html
```html
{% if not username %}
<form method="post" action="/login/">
用户名:<input type="text" name="username" value=""><br/>
<input type="submit" value="登录">
</form>
{% else %}
你已经登录了!{{ username }}<br/>
<form method="post" action="/logout/">
<input type="submit" value="注销">
</form>
{% endif %}
```
整个是一个 `if` 语句。在 Django 模板中的 `if` 可以象 Python 一样使用,如使用 `not` , `and` , `or` 。象 `if not username` 表示什么呢?它表示如果 username 不存在,或为空,或是假值等等。而此时我们利用了 `username` 不存在这种判断。
上面的逻辑表示,如果 `username` 不存在,则显示一个表单,显示用户名输入文本框。如果存在,则显示已经登录信息,同时显示用户名和注销按钮。而这个注销铵钮对应于 `logout()` 方法。
## 4 修改 urls.py
```python
from django.conf.urls import url
from django.contrib import admin
from . import helloworld, add, list, xls_test, login
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^$', helloworld.index),
url(r'^add/$', add.index),
url(r'^list/$', list.index),
url(r'^xls/(?P<filename>\w+)/$', xls_test.output),
url(r'^login/$', login.login),
url(r'^logout/$', login.logout),
]
```
增加了 login 和 logout 两个url映射。
## 5 启动 server 运行
但我要说,你一定会报错。而且我的也在报错。为什么,因为从这一刻起,我们就要进入有数据库的环境了。因为在 django 中 session 是存放在数据库中的。所以在这里要进行数据库的初始化了。
## 6 查看 settings.py
我们在创建newtest工程的时候,Django已经为我们默认生成了数据库处理的配置:
```python
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
}
}
```
这里使用的是 sqlite3 。在使用数据库时,你同时需要自已去安装相应的数据库处理模块。
## 7 初始化数据库
配置不需要做什么修改,下一步我们进行数据库的初始化工作,包括建库、建表等:
```shell
python manage.py migrate
```
## 8 启动 server
这次再进入试吧
(http://localhost:8000/login/)
从此我们要进入数据库的世界了,当然目前还没有用到,而 Django 提供的许多自动化的高级功能都是需要数据库支持的。
- 开始学习
- 搭建Python开发环境
- 简明Python教程
- 致敬
- 前言
- 关于Python
- 安装
- 第一步
- 基础
- 运算符和表达式
- 控制流
- 函数
- 模块
- 数据结构
- 实战案例
- 面向对象编程
- 输入与输出
- 异常处理
- 标准库
- 更多
- 继续学习
- 附录:免费/自由和开放源码软件
- 附录: 关于
- 附录: 版本历史
- 附录: 翻译
- 附录: 参与翻译工作
- 反馈
- Django Step Sy Step
- 第一讲 从简单到复杂
- 第二讲 做加法的例子
- 第三讲 使用Template
- 第四讲 生成csv格式文件
- 第五讲 session示例
- 第六讲 wiki的例子
- 第七讲 通讯录的例子
- 第八讲 文件导入和导出
- 第九讲 通讯录的美化
- 第十讲 扩展django的模板
- 第十一讲 用户管理
- 第十二讲 搜索和部署
- 第十三讲 Ajax的实现(一)
- 第十四讲 Ajax的实现(二)
- 第十五讲 i18n的一个简单实现
- 第十六讲 自定义Calendar Tag
- 第十七讲 View,Template和Tag
- Django开发实战
- Python开发规范
- Django项目的gitignore
- 怎样配置开发环境的settings
- 如何使用Django和Vue.js构建项目
- 使用WebSocket开发网页聊天室
- 怎样使Django Admin显示中文
- 怎样使Model在Admin界面中显示中文
- 使用Django Admin怎样上传并显示图片
- 解决Django模板和Vue指令花括号冲突的问题
- 使用Django和Vue开发微信公众号
- 使用Django和Vue调用微信JSSDK开发微信支付