3.Django的模板和其他内容
3.1 模板
1. 配置模板
1.1 准备模板文件目录
- 在工程根目录下创建模板文件目录**
templates
**
1.2 配置模板
-
在
settings.py
配置文件中修改
TEMPLATES
配置项的
DIRS
值:
# 配置模板 TEMPLATES = [ { 'BACKEND': 'django.template.backends.django.DjangoTemplates', #指定模板文件目录的路径 'DIRS': [os.path.join(BASE_DIR, 'templates')], 'APP_DIRS': True, 'OPTIONS': { 'context_processors': [ 'django.template.context_processors.debug', 'django.template.context_processors.request', 'django.contrib.auth.context_processors.auth', 'django.contrib.messages.context_processors.messages', ], }, }, ]
2. 定义和响应模板
2.1 新建模板文件
- 在
templates
目录中新建一个模板文件,如:temp.html
2.2 响应模板文件
class TempView(View):
"""图书信息
http://127.0.0.1:8000/temp/
"""
def get(self, request):
return render(request, 'temp.html')
3. 测试模板渲染
3.1 模板语法
- 模板语法如下:
- 变量名必须由字母、数字、下划线(不能以下划线开头)和点组成
3.2 使用模板语法渲染HTML模板
class BooksView(View):
"""图书信息
http://127.0.0.1:8000/books/
"""
def get(self, request):
# 构造上下文
context = {
'name': '张小厨',
'age': 18
}
# 使用上下文渲染'book.html',并返回给客户端
return render(request, 'book.html', context)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>图书信息页</title>
</head>
<body>
<h1>{{ name }}</h1>
<h1>{{ age }}</h1>
</body>
</html>
4. 数据库数据渲染模板
- 渲染数据库中所有的图书信息
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>图书信息</title>
</head>
<body>
<h1>全部图书信息</h1>
<table>
<tr>
<th>图书名</th>
<th>发行日期</th>
<th>阅读量</th>
</tr>
{% for book in books %}
<tr>
<td>{{ book.btitle }}</td>
<td>{{ book.bpub_date }}</td>
<td>{{ book.bread }}</td>
{# <td>{{ xxx.0 }}</td>#}
{# 如果是取列表中的一个值#}
</tr>
{% endfor %}
</table>
</body>
</html>
class BooksView(View):
'''
显示图书名
'''
def get(self, request):
# 1.访问数据库获取查询的数值
books = BookInfo.objects.all()
# 2.定义需要替换的模板内容
context = {
'books': books
}
return render(request, 'book.html', context)
3.2 Cookie
- HTTP协议本身是无状态的,即服务器无法判断用户身份。
问题:
- 服务器默认是无法识别当前登录用户是谁的,即无法记住登录状态。
解决:
Cookie
- 我们可以使用Cookie机制记住用户的登录状态
1. Cookie的介绍
- Cookie,最早是网景公司的前雇员 Lou Montulli 在 1993 年 3 月发明的。
- Cookie,指某些网站为了辨别用户身份、进行session跟踪而储存在用户本地终端上的数据(通常经过加密)。
- Cookie,实际上是一小段存储在用户浏览器中的文本信息。
Cookie的机制:
- 客户端向服务器发起请求,如果服务器需要记录该用户状态,就通过响应向客户端浏览器颁发一个Cookie。
- 该Cookie中需要包含用户的唯一标识信息
- 客户端浏览器会把Cookie保存起来。
- 当浏览器再次请求该网站时,浏览器把请求的网址连同该Cookie一同提交给服务器。
- 服务器检查该Cookie,以此来辨认用户状态。
Cookie的特点:
-
Cookie,以键值对**
Key-Value
**形式进行信息的存储 -
Cookie,基于域名安全,不同域名的
Cookie
是不能互相访问的
- 例如: 保存在
www.baidu.com
域名下面的Cookie
是不能被其他域名访问的
- 例如: 保存在
-
Cookie,它会自动跟随当前的请求传递到对应域名所在的服务器中。
2. 操作Cookie
提示:
- 关于操作Cookie,分为设置Cookie和读取Cookie
2.1 设置Cookie
可以通过**HttpResponse()对象中的set_cookie()
**方法来设置Cookie。
# 创建响应对象
response = HttpResponse()
# 使用响应对象设置Cookie
response.set_cookie(key, value, max_age=cookie有效期)
- 响应对象:常见的构造响应对象的方式
HttpResponse()
:响应多种数据类型JsonResponse()
:响应JSONredirect()
:重定向render()
:渲染并响应HTML模板
- max_age:单位为秒,默认为None。
- 如果是临时Cookie,可将
max_age
设置为None
。 - 如果是有具体有效期的Cookie,可将
max_age
设置为具体的秒数
。
- 如果是临时Cookie,可将
示例:
class BooksView(View):
"""测试模板
http://127.0.0.1:8000/books/
"""
def get(self, request):
# 查询所有图书信息
books = BookInfo.objects.all()
# 构造上下文
context = {
'books': books
}
# 使用上下文渲染'book.html',并返回给客户端
response = render(request, 'books.html', context)
# 设置Cookie
response.set_cookie('name', 'itcast', max_age=None)
# 响应结果,并写Cookie到浏览器
return response
2.2 读取Cookie
可以通过HttpRequest对象的**COOKIES
**属性来读取本次请求携带的cookie值。
class TestCookieView(View):
"""测试Cookie
http://127.0.0.1:8000/cookies/
"""
def get(self, request):
# 读取Cookie
name = request.COOKIES.get('name')
print(name)
return http.HttpResponse('测试Cookie')
3. Session
-
Cookie中存储敏感信息是否安全?
-
如果存储前做加密处理,就会是安全的,但是加密后的敏感信息依然会暴露在浏览器中
-
有没有一种方式可以将某些敏感数据存储的更加安全些,即加密又不会暴露出去?
解决:
Session
1. Session的介绍
-
Session,是一种会话控制方式。由服务端创建,并且保存在服务端的数据存储形式。
-
Session,内部也是以**
key-value
** 键值对的形式存储数据。 -
Session,有些内容会被加密,所以可以存储敏感信息。
-
处理Session数据的子应用:
-
处理Session的中间件:
PS:如需禁用Session,将上图中的session中间件注释掉即可。
Session的机制:
- 客户端向服务器发起请求,如果服务器需要记录该用户状态,就可以通过Session在服务端将该用户的唯一标识信息存储起来。
session_key
:一个随机的唯一的不重复的字符串session_data
:用户的唯一标识信息(密文)
- 然后,服务端会向客户端浏览器颁发一个Cookie。
- 该Cookie中包含了Session存储数据时使用的那个**
session_key
** - 该Cookie的具体形式为:
'sessionid': 'session_key'
- 该Cookie中包含了Session存储数据时使用的那个**
- 当浏览器再次请求该网站时,浏览器把请求的网址连同该Cookie一同提交给服务器。
- 服务器提取该Cookie中的**
session_key
,再使用它提取session_data
**。 - 最后使用**
session_data
**来辨认用户状态
Session的特点:
- 存储敏感、重要的信息
- 因为session数据是存储在服务端的,不会直接暴露给用户
- 相比较Cookie可以存储更多的内容
- 不同的浏览器,对Cookie都有不同的数量和大小的限制
- 依赖于Cookie
- 因为**
session_key
**需要存储在Cookie中
- 因为**
- Session共享
- 利用独立部署的session服务器(集群)统一管理Session,服务器每次读写Session时,都访问Session服务器。
2. 操作Session
提示:
- 对于Session的操作,分为**
设置Session
和读取session
**
2.1 设置Session
可以通过**HttpRequest()对象中的session
**属性来设置Session。
request.session['key'] = value
class BooksView(View):
"""测试模板
http://127.0.0.1:8000/books/
"""
def get(self, request):
# 查询所有图书信息
books = BookInfo.objects.all()
# 构造上下文
context = {
'books': books
}
# 使用上下文渲染'book.html',并返回给客户端
response = render(request, 'books.html', context)
# 设置Cookie
response.set_cookie('name', 'itcast', max_age=3600)
# 设置Session
request.session['name'] = 'itcast'
# 响应结果,并写Cookie到浏览器
return response
2.2 读取Session
根据键读取值
request.session.get('key', 默认值)
class TestSessionView(View):
"""测试Session
http://127.0.0.1:8000/session/
"""
def get(self, request):
# 读取Session
name = request.session.get('name')
print(name)
return http.HttpResponse('测试Session')
2.3 操作Session的其他方式
清除所有Session,在存储中删除值部分。
request.session.clear()
清除session数据,在存储中删除session的整条数据。
request.session.flush()
删除session中的指定键及值,在存储中只删除某个键及对应的值。
del request.session['key']
设置session的有效期
request.session.set_expiry(value)
- 如果value是一个整数,session将在value秒没有活动后过期。
- 如果value为0,那么用户session的Cookie将在用户的浏览器关闭时过期。
- 如果value为None,那么session有效期将采用系统默认值,默认为两周。
- 可以通过在settings.py中设置SESSION_COOKIE_AGE来设置全局默认值。
3. Session数据存储的位置
3.1 默认的存储位置
Session数据默认存储的位置是在
settings.py
的DATABASES
配置项指定的SQL数据库中
-
因为Session引擎默认的配置为:
SESSION_ENGINE = 'django.contrib.sessions.backends.db'
-
数据库中的表如图所示
- 表结构如下
由表结构可知,操作Session包括三个数据:键,值,过期时间。
3.2 本地缓存
存储在本机内存中,如果丢失则不能找回,比数据库的方式读写更快。
SESSION_ENGINE='django.contrib.sessions.backends.cache'
3.3 混合存储
优先从本机内存中存取,如果没有则从数据库中存取。
SESSION_ENGINE='django.contrib.sessions.backends.cached_db'
3.4 Redis
在Redis中保存Session,需要引入第三方扩展,我们可以使用django-redis来解决。
1)安装扩展
pip install django-redis
2)配置
在settings.py文件中做如下设置
CACHES = {
"default": {
"BACKEND": "django_redis.cache.RedisCache",
# redis:ip地址/数据库
"LOCATION": "redis://127.0.0.1:6379/1",
"OPTIONS": {
"CLIENT_CLASS": "django_redis.client.DefaultClient",
}
}
}
SESSION_ENGINE = "django.contrib.sessions.backends.cache"
SESSION_CACHE_ALIAS = "default"