一、模板语言 

1、在前段展示:对象/字典/元组

class Business(models.Model):
# id #用默认的自增id列 即:Business中有3列数据(id, caption, code)
caption = models.CharField(max_length=32)
code = models.CharField(max_length=32,default="SA")

#models.py

from django.shortcuts import render,HttpResponse,redirect
from app01 import models
# Create your views here.
def business(request):
# 以下得到的都是QuerySet类型数据(类似于列表)
v1 = models.Business.objects.all() # ①得到的是business obj对象 [obj(id,caption,code),obj(id,caption,code), ]
v2 = models.Business.objects.all().values('id','caption') # ②得到的是字典 [{'id':1,'caption': '运维部'},{'id':1,'caption': '运维部'},...]
v3 = models.Business.objects.all().values_list('id','caption') # ③得到的是元组 [(1,运维部),(2,开发)]
return render(request, 'business.html', {'v1': v1,'v2': v2, 'v3': v3})
#前端的三种形式:
# {% for row in v %}
# ① <li>{{ row.id }} - {{ row.caption }} - {{ row.code }}</li>
# ② <li>{{ row.id }} - {{ row.caption }} - {{ row.code }}</li>
# ③ <li>{{ row.0 }} - {{ row.1 }} - {{ row.1 }</li>
# {% endfor %}

#views.py

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title></title>
</head>
<body>
<h1>业务线列表(对象)</h1>
<ul>
{% for row in v1 %}
<li>{{ row.id }} - {{ row.caption }} - {{ row.code }}</li>
{% endfor %}
</ul>
<h1>业务线列表(字典)</h1>
<ul>
{% for row in v2 %}
<li>{{ row.id }} - {{ row.caption }}</li>
{% endfor %}
</ul>
<h1>业务线列表(元组)</h1>
<ul>
{% for row in v3 %}
<li>{{ row.0 }} - {{ row.1 }}</li>
{% endfor %}
</ul>
</body>
</html>

#business.html

from django.conf.urls import url
from django.contrib import admin from app01 import views
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^business$', views.business), #加上终止符($)防止business匹配完成后以下的business_add不再执行
]

#urls.py

INSTALLED_APPS = [
'app01',
]

#settings.py

2、排序
① forloop.counter 表示循环的次数,它从1开始计数,第一次循环设为1

{% for item in todo_list %}
<p>{{ forloop.counter }}: {{ item }}</p>
{% endfor %}

② forloop.counter0 表示循环的次数,它从0开始计数,第一次循环设为0

{% for item in todo_list %}
<p>{{ forloop.counter0 }}: {{ item }}</p>
{% endfor %}

③ forloop.revcounter  示循环中剩下的items数量,第一次循环时设为items总数,最后一次设为1

{% for item in todo_list %}
<p>{{ forloop.revcounter }}: {{ item }}</p>
{% endfor %}

④ forloop.revcounter0 类似于forloop.revcounter,但它是表示的数量少一个,即最后一次循环时设为0

{% for item in todo_list %}
<p>{{ forloop.revcounter0 }}: {{ item }}</p>
{% endfor %}

⑤ forloop.first 当第一次循环时值为True,在特别情况下很有用)

{% for object in objects %}
{% if forloop.first %}<li class="first">{% else %}<li>{% endif %}
{{ object }}
</li>
{% endfor %}

⑥ forloop.last 当最后一次循环时值为True

{% for link in links %}{{ link }}{% if not forloop.last %} | {% endif %}{% endfor %}

⑦ forloop.parentloop 在嵌套循环中表示父循环的forloop:

{% for country in countries %}
<table>
{% for city in country.city_list %}
<tr>
<td>Country #{{ forloop.parentloop.counter }} </td>
<td>City #{{ forloop.counter }}</td>
<td>{{ city }}</td>
</tr>
{% endfor %}
</table>
{% endfor %}

3、继承
①模板继承允许你建立一个基本的”骨架”模板, 它包含你所有最常用的站点元素 并 定义了一些可以被子模板覆盖的block。
注:一个html页面只能继承一个父模板,不能继承多个

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>{% block title %}{% endblock %}</title>
<style>
.body-header{
background-color: black;
}
</style>
</head>
<body>

#父模板(master.html)

{# 指定继承的模板 #}
{% extends 'master.html' %} {# 指定替换的位置 #}
{% block title %}
tp1
{% endblock %} {# 指定替换的位置 #}
{% block content %}
<p>tp1</p>
{% endblock %}

#HTML页面

②模板导入定制的组件include

<form>
<input type="text" name="user"/>
<input type="submit" value="提交"/>
</form>

#组件(tag.html)

{# 指定继承的模板 #}
{% extends 'master.html' %} {# 指定替换的位置 #}
{% block title %}
tp1
{% endblock %} {# 指定替换的位置 #}
{% block content %}
<p>tp1</p> {# 导入单独组件 #}
{% include 'tag.html' %}
{% endblock %}

#HTML页面

4、Simplelistfilter
有时候我们需要在html上对后台渲染的页面进行二次处理,比如把字符串的首字母大写、字符进行计算操作等。
(1)django默认自带方法

{{ item.event_start|date:"Y-m-d H:i:s"}}    #日期格式进行转换
{{ bio|truncatewords:"" }} #取字符串前30位
{{ my_list|first|upper }} #第一个字符大写
{{ name|lower }} #所有字符小写

(2)自定义simple_tag、filter
① 在app中创建templatetags文件夹
② templatetags中创建任意 .py 文件,如:handle.py

from django import template
from django.utils.safestring import mark_safe register = template.Library() @register.simple_tag()
def sub(a1,a2):    #能添加多个参数
return a1 + a2 @register.filter()  
def lzl(a1,a2):    #只能传入两个参数
return a1 + a2

#handle.py

③ 在settings中配置当前app,不然django无法找到自定义的simple_tag

INSTALLED_APPS = (
......
'cmdb',
)

#settings.py

④ 导入和使用simple_tag、filter

{# 导入py文件名 #}
{% load handle %}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div>{{ name|lower }}</div>
<div>{{ name|upper }}</div> {% sub 1 2 %} {{ 'hello'|lzl:'world'}}
</body>
</html> {#页面内容#}
{#3 helloworld#}

#html

(3)django数据库choice获取字段

device_status_choices = (
(1, '上架'),
(2, '在线'),
(3, '离线'),
(4, '下架'),
)
device_type_id = models.IntegerField('设备类型',choices=device_type_choices, default=1)
<td colspan="">{{ response.data.asset.get_device_status_id_display }}</td>

 二、分页 

1、简单分页
涉及xss攻击,需要用到mark_safe方法,使用此方法字符串传输到后端后,已html形式显示,而非字符串
分页数进行定制,添加上一页、下一页,增加跳转功能,实现分页的完整功能 

  ① 设定每页显示数据条数
  ② 用户输入页码(第一页、第二页...)
  ③ 设定显示多少页号
  ④ 获取当前数据总条数
  ⑤ 根据设定显示多少页号和数据总条数计算出,总页数
  ⑥ 根据设定的每页显示条数和当前页码,计算出需要取数据表的起始位置
  ⑦ 在数据表中根据起始位置取值,页面上输出数据
  ⑧ 输出分页html,如:[上一页][1][2][3][4][5][下一页]

from app01 import views
urlpatterns = [
.....
url(r'^user_list/', views.user_list),
]

#urls.py

LIST = []
for i in range(109):
LIST.append(i) from django.utils.safestring import mark_safe #
def user_list(request):
current_page = request.GET.get('p',1) # 通过输入p页,利用get方法获取当前页码。不输入默认为第1页。得到的是一个字符串。
current_page = int(current_page) # 把字符串 --> 数字 start = (current_page-1)*10 # 起始页
end = current_page*10 # 结束页
data = LIST[start:end] # 起始页--结束页的所有数据 all_count = len(LIST) # 总数据个数
total_count,y = divmod(all_count,10) # 总页面数,每页多少条数据;divmod():整除,余数
if y : # 存在余数,总页面数+1
total_count +=1 pager_num = 11 # (显示的)页码数
page_list = [] #
if total_count < pager_num : # ①总页面数 <(显示的)页码数
start_index = 1
end_index = total_count + 1
else: # ②总页面数 >=(显示的)页码数
if current_page <= pager_num/2: #【开头】
start_index = 1 # 首页
end_index = pager_num + 1
elif current_page + (pager_num-1)/2 >= total_count: #【中间】
start_index = total_count - (pager_num-1)
end_index = total_count + 1
else: #【结尾】
start_index = current_page - (pager_num-1)/2
end_index = current_page + (pager_num-1)/2 + 1 #最后一页 # 上下页码
if current_page == 1:
prev = '<a class="page" href="javascript:void(0)">上一页</a>' # 什么都不干
else:
prev = '<a class="page" href="/user_list/?p=%s">上一页</a>'%(current_page-1)
page_list.append(prev)
for i in range(int(start_index),int(end_index)): #循环所有页码,选中的页码(当前页)改变样式,没选中的不改变样式
if i == current_page:
temp = '<a class="page active" href="/user_list/?p=%s">%s</a>'%(i,i)
else:
temp = '<a class="page" href="/user_list/?p=%s">%s</a>'%(i,i) page_list.append(temp)
if current_page == total_count:
nex = '<a class="page" href="javascript:void(0)">下一页</a>' # 什么都不干
else:
nex = '<a class="page" href="/user_list/?p=%s">下一页</a>'%(current_page+1)
page_list.append(nex) # 跳转 可以写到前端
jump = '''
<input type="text" /><a onclick="jumpTo(this,'/user_list/?p=');">GO</a>
<script>
function jumpTo(ths,base) {
var val = ths.previousSibling.value;
location.href = base + val;
}
</script>
'''
page_list.append(jump) page_str = mark_safe(''.join(page_list)) # mark_safe(防止XSS攻击,否侧page_str传到前端显示的是字符串,而不是html语言)
# 另一种方式在前端做
# {{ page_str|safe }} #(''.join(page_list)):将所有的页码以空字符串进行拼接
return render(request,'user_list.html',{'li':data,'page_str':page_str})

#views.py

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
.pagination .page{
display: inline-block;
padding: 5px;
background-color: cyan;
margin: 5px;
}
.pagination .page.active{
background-color: brown;
color: white;
}
</style>
</head>
<body>
<ul>
{% for item in li %}
<li>{{ item }}</li>
{% endfor %}
</ul>
<div class="pagination">
{{ page_str }}
</div>
</body>
</html>

#user_list.html

改进:页码代码跟业务代码分开,创建class类调用,最好单独创建目录分开

from app01 import views
urlpatterns = [
.....
url(r'^user_list/', views.user_list),
]

#urls.py

LIST = []
for i in range(199):
LIST.append(i) class Page:
def __init__(self, current_page, data_count, per_page_count=10, pager_num=7):
self.current_page = current_page
self.data_count = data_count
self.per_page_count = per_page_count
self.pager_num = pager_num @property # 利用属性方法:把方法变成静态属性
def start(self):
return (self.current_page - 1) * self.per_page_count @property
def end(self):
return self.current_page * self.per_page_count @property
def total_count(self):
v, y = divmod(self.data_count, self.per_page_count)
if y:
v += 1
return v def page_str(self, base_url):
page_list = [] if self.total_count < self.pager_num: #self调用方法是不用加 ()
start_index = 1
end_index = self.total_count + 1
else:
if self.current_page <= (self.pager_num + 1) / 2:
start_index = 1
end_index = self.pager_num + 1
else:
start_index = self.current_page - (self.pager_num - 1) / 2
end_index = self.current_page + (self.pager_num + 1) / 2
if (self.current_page + (self.pager_num - 1) / 2) > self.total_count:
end_index = self.total_count + 1
start_index = self.total_count - self.pager_num + 1 if self.current_page == 1:
prev = '<a class="page" href="javascript:void(0);">上一页</a>'
else:
prev = '<a class="page" href="%s?p=%s">上一页</a>' % (base_url, self.current_page - 1,)
page_list.append(prev) for i in range(int(start_index), int(end_index)):
if i == self.current_page:
temp = '<a class="page active" href="%s?p=%s">%s</a>' % (base_url, i, i)
else:
temp = '<a class="page" href="%s?p=%s">%s</a>' % (base_url, i, i)
page_list.append(temp) if self.current_page == self.total_count:
nex = '<a class="page" href="javascript:void(0);">下一页</a>'
else:
nex = '<a class="page" href="%s?p=%s">下一页</a>' % (base_url, self.current_page + 1,)
page_list.append(nex) jump = """
<input type='text' /><a onclick='jumpTo(this, "%s?p=");'>GO</a>
<script>
function jumpTo(ths,base){
var val = ths.previousSibling.value;
location.href = base + val;
}
</script>
""" % (base_url,) page_list.append(jump) page_str = mark_safe("".join(page_list)) return page_str

#pagination.py

from django.utils.safestring import  mark_safe
def user_list(request):
current_page = request.GET.get('p', 1)
current_page = int(current_page)
page_obj = Page(current_page,len(LIST)) data = LIST[page_obj.start:page_obj.end] page_str = page_obj.page_str("/user_list/") return render(request, 'user_list.html', {'li': data,'page_str': page_str})

#views.py

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
.pagination .page{
display: inline-block;
padding: 5px;
background-color: cyan;
margin: 5px;
}
.pagination .page.active{
background-color: brown;
color: white;
}
</style>
</head>
<body>
<ul>
{% for item in li %}
<li>{{ item }}</li>
{% endfor %}
</ul>
<div class="pagination">
{{ page_str }}
</div>
</body>
</html>

#user_list.html

三、Cookie 

1、概述
Cookie,有时也用其复数形式 Cookies,指某些网站为了辨别用户身份、进行 session 跟踪而储存在用户本地终端上的数据(通常经过加密)。(可以叫做浏览器缓存:Cookie就是一段字符串,保存于本机电脑上。)
① 获取Cookie

request.COOKIES['key']
request.COOKIES.get('key')
request.get_signed_cookie(key, default=RAISE_ERROR, salt='', max_age=None)
参数:
default: 默认值
salt: 加密盐
max_age: 后台控制过期时间

#views.py

② 设置Cookie

rep = HttpResponse(...) 或 rep = render(request, ...) #return的对象

rep.set_cookie(key,value,...)
rep.set_signed_cookie(key,value,salt='加密盐',...)
参数:
key, 键
value='', 值
max_age=None, 超时时间 单位秒
expires=None, 超时时间(IE requires expires, so set it if hasn't been already.) 单位日期
path='/', Cookie生效的路径,/ 表示根路径,特殊的:跟路径的cookie可以被任何url的页面访问 指定生效路径
domain=None, Cookie生效的域名
secure=False, https传输改为True
httponly=False 只能http协议传输,无法被JavaScript获取(不是绝对,底层抓包可以获取到也可以被覆盖) 补充:
# max_age 10秒失效
result.set_cookie('username',u,max_age=10) # expires 设置失效日期
import datetime
current_date = datetime.datetime.utcnow() # utcnow()当前时间
current_date = current_date + datetime.timedelta(seconds=5) # timedelta时间差
result.set_cookie('username',u,expires=current_date) # 加密(带签名的)
obj = HttpResponse('s')
obj.set_signed_cookie('username',"kangbazi",salt="asdfasdf") #加密
request.get_signed_cookie('username',salt="asdfasdf") # 解密 注:由于cookie保存在客户端的电脑上,所以,JavaScript和jquery也可以操作cookie
<script src='/static/js/jquery.cookie.js'></script>
$.cookie("list_pager_num", 30,{ path: '/' }); #key vaule 字典

2、用户登录
利用cookie做用户登录页面,只有登录成功才能进入到后台管理

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title></title>
</head>
<body>
<h1>欢迎登录:{{ current_user }}</h1>
</body>
</html>

#index.html

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title></title>
</head>
<body>
<form action="/login/" method="POST">
<input type="text" name="username" placeholder="用户名" />
<input type="password" name="pwd" placeholder="密码" />
<input type="submit" />
</form>
</body>
</html>

#login.html

user_info = {
'solo':{'pwd':''}
} def login(request):
if request.method == 'GET':
return render(request,'login.html')
if request.method == 'POST':
u = request.POST.get('username')
p = request.POST.get('pwd')
dic = user_info.get(u)
if not dic:
return render(request,'login.html')
if dic['pwd']== p:
result = redirect('/index/')
result.set_cookie('username',u) #设置cookie值
return result
else:
return render(request, 'login.html') def index(request):
v = request.COOKIES.get('username') #获取cookie值
if not v :
return redirect('/login/')
return render(request,'index.html',{'current_user':v})

#views.py

3、定制分页
根据用户选择的数字,显示页面的数量

<body>
<ul>
{% for item in li %}
<li>{{ item }}</li>
{% endfor %}
</ul>
<div>
<select id='pg' onchange="ChangePageSize(this)"> #给选中的页面增加一个事件
<option value="10">10</option>
<option value="30">30</option>
<option value="50">100</option>
</select>
</div>
<div class="pagination">
{{ page_str }}
</div>
<script src="/static/jquery-1.12.4.js"></script>
<script src="/static/jquery.cookie.js"></script> #注意顺序
<script> $(function () { # 页面加载完成后执行此方法
var v = $.cookie('per_page_count',{'path':'/user_list/'});#获取选中的值,设置为新一页的默认值;路径:只有当前页面受影响
$('#pg').val(v);
}); function ChangePageSize(ths) {
var v = $(ths).val(); # 获取用户当前选择的值
$.cookie('per_page_count',v,{'path':'/user_list/'});
location.reload()
}
</script>
</body>

#user_list.html

from django.utils.safestring import  mark_safe
def user_list(request):
current_page = request.GET.get('p', 1)
current_page = int(current_page) per_page_count = request.COOKIES.get('per_page_count',10) #获取cookie值
per_page_count = int(per_page_count) page_obj = Page(current_page,len(LIST),per_page_count) data = LIST[page_obj.start:page_obj.end] page_str = page_obj.page_str("/user_list/") return render(request, 'user_list.html', {'li': data,'page_str': page_str})

# views.py

4、登录认证(装饰器)
①FBV

def auth(func):
def inner(request,*args,**kwargs):
v = request.COOKIES.get('username') # 获取cookie值
if not v:
return redirect('/login/')
return func(request,*args,**kwargs)
return inner @auth #认证装饰
def index(request):
v = request.COOKIES.get('username')
return render(request, 'index.html', {'current_user': v})

②CBV

def auth(func):
def inner(request,*args,**kwargs):
v = request.COOKIES.get('username') # 获取cookie值
if not v:
return redirect('/login/')
return func(request,*args,**kwargs)
return inner from django import views
from django.utils.decorators import method_decorator @method_decorator(auth,name='dispatch') #第一种方式
class Order(views.View): # @method_decorator(auth) #第二种方式
# def dispatch(self, request, *args, **kwargs):
# return super(Order,self).dispatch(request, *args, **kwargs) # @method_decorator(auth) #单独添加
def get(self,reqeust):
v = reqeust.COOKIES.get('username111')
return render(reqeust,'index.html',{'current_user': v}) def post(self,reqeust):
v = reqeust.COOKIES.get('username111')
return render(reqeust,'index.html',{'current_user': v})

三、Session   
1、概述
两者区别:Cookie是保存在用户浏览器端的键值对,Session是保存在服务器端的键值对;Cookie做用户验证的时,敏感信息不适合放在Cookie中,别人可以分析存放在本地的Cookie并进行Cookie欺骗,考虑到安全应当使用Session;用户验证时两者要结合使用,Session可保存到文件,内存,数据库任意地方。 (session 保存于服务器,用来保存用户的会话信息,依赖于Cookies)
① 获取

# 获取Session中数据
request.session['k1']
request.session.get('k1', None)

② 生成

# 生成Session中数据
request.session['k1'] = 123
request.session.setdefault('k1', 123) # 存在则不设置

③ 删除

# 删除Session中某条数据
del request.session['k1'] # 删除当前用户的所有Session数据
request.session.delete("session_key")
request.session.clear() #注销时可用

④ 键值对

# 所有 键、值、键值对
request.session.keys()
request.session.values()
request.session.items()
request.session.iterkeys()
request.session.itervalues()
request.session.iteritems()

⑤ 超时时间

# 设置超时时间
request.session.set_expiry(value) #默认超时时间为两周
*如果value是个整数,session会在些秒数后失效。
*如果value是个datatime或timedelta,session就会在这个时间后失效。
*如果value是0, 用户关闭浏览器session就会失效。
*如果value是None, session会依赖全局session失效策略。

⑥ 其他

# 用户session的随机字符串
request.session.session_key # 将所有Session失效日期小于当前日期的数据删除
request.session.clear_expired() # 检查 用户session的随机字符串 在数据库中是否 一般用不到
request.session.exists("session_key")

2、用户登录
利用Session做用户登录页面,只有登录成功才能进入到后台管理

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<form action="/login/" method="post">
<input type="text" name="user" />
<input type="text" name="pwd" />
<input type="checkbox" name="session" value="1"/> 保存1个月
<input type="submit" value="提交" />
</form>
</body>
</html>

#login.html

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
{{ request.session.username }}
</body>
</html>

#index.html

def login(request):
if request.method == 'GET':
return render(request,'login.html')
elif request.method == 'POST':
user = request.POST.get('user')
pwd = request.POST.get('pwd')
if user == 'root' and pwd == "123":
# 生成随机字符串
# 写到用户浏览器Cookie
# 保存到Session中
# 在随机字符串对应的字典中设置相关内容...
request.session['username'] = user
request.session['if_login'] = True #可不加 直接判断username也可以
if request.POST.get('session') == '1': #单独设置超时时间,当前session生效,不影响全局
request.session.set_expiry(10) #10秒
return redirect('/index/')
else:
return redirect('/login/') def index(request):
# 获取当前用户的随机字符串
# 根据随机字符串获取对应信息
if request.session.get('if_login'):
return render(request, 'index.html')
else:
return redirect('/login/')

#vars.py

3、Django中默认支持Session,其内部提供了5种类型的Session供开发者使用:
①数据库Session(默认)

Django默认支持Session,并且默认是将Session数据存储在数据库中,即:django_session 表中。

a. 配置 settings.py

    SESSION_ENGINE = 'django.contrib.sessions.backends.db'   # 引擎(默认)

    SESSION_COOKIE_NAME = "sessionid"                       # Session的cookie保存在浏览器上时的key,即:sessionid=随机字符串(默认)
SESSION_COOKIE_PATH = "/" # Session的cookie保存的路径(默认)
SESSION_COOKIE_DOMAIN = None # Session的cookie保存的域名(默认)
SESSION_COOKIE_SECURE = False # 是否Https传输cookie(默认)
SESSION_COOKIE_HTTPONLY = True # 是否Session的cookie只支持http传输(默认)
SESSION_COOKIE_AGE = 1209600 # Session的cookie失效日期(2周)(默认)
SESSION_EXPIRE_AT_BROWSER_CLOSE = False # 是否关闭浏览器使得Session过期(默认)
SESSION_SAVE_EVERY_REQUEST = False # 是否每次请求都保存Session,默认修改之后才保存(默认) b. 使用 def index(request):
# 获取、设置、删除Session中数据
request.session['k1']
request.session.get('k1',None)
request.session['k1'] = 123
request.session.setdefault('k1',123) # 存在则不设置
del request.session['k1'] # 所有 键、值、键值对
request.session.keys()
request.session.values()
request.session.items()
request.session.iterkeys()
request.session.itervalues()
request.session.iteritems() # 用户session的随机字符串
request.session.session_key
# 将所有Session失效日期小于当前日期的数据删除
request.session.clear_expired()
# 检查 用户session的随机字符串 在数据库中是否
request.session.exists("session_key")
# 删除当前用户的所有Session数据
request.session.delete("session_key") request.session.set_expiry(value)
* 如果value是个整数,session会在些秒数后失效。
* 如果value是个datatime或timedelta,session就会在这个时间后失效。
* 如果value是0,用户关闭浏览器session就会失效。
* 如果value是None,session会依赖全局session失效策略。

②缓存存储Session
可以设置为Memcache缓存,默认不支持redis(可以使用网上插件)

#本地内存存储session
配置settings.py SESSION_ENGINE = 'django.contrib.sessions.backends.cache' # 引擎
SESSION_CACHE_ALIAS = 'default' # 使用的缓存别名(默认内存缓存,也可以是memcache),此处别名依赖缓存的设置 SESSION_COOKIE_NAME = "sessionid" # Session的cookie保存在浏览器上时的key,即:sessionid=随机字符串
SESSION_COOKIE_PATH = "/" # Session的cookie保存的路径
SESSION_COOKIE_DOMAIN = None # Session的cookie保存的域名
SESSION_COOKIE_SECURE = False # 是否Https传输cookie
SESSION_COOKIE_HTTPONLY = True # 是否Session的cookie只支持http传输
SESSION_COOKIE_AGE = 1209600 # Session的cookie失效日期(2周)
SESSION_EXPIRE_AT_BROWSER_CLOSE = False # 是否关闭浏览器使得Session过期
SESSION_SAVE_EVERY_REQUEST = False # 是否每次请求都保存Session,默认修改之后才保存 #Memcache缓存
配置settings.py SESSION_ENGINE = 'django.contrib.sessions.backends.cache' # 引擎
SESSION_CACHE_ALIAS = 'db' # 使用的缓存别名,此处别名依赖缓存的设置 CACHES = {
'default': {
'BACKEND': 'django.core.cache.backends.memcached.MemcachedCache',
'LOCATION': [
'172.19.26.240:11211',
'172.19.26.242:11211',
]
},
'db': {
'BACKEND': 'django.core.cache.backends.memcached.MemcachedCache',
'LOCATION': [
'172.19.26.240:11211',
'172.19.26.242:11211',
]
}
}

③文件存储Session

#文件session
配置 settings.py SESSION_ENGINE = 'django.contrib.sessions.backends.file' # 引擎
SESSION_FILE_PATH = None # 缓存文件路径,如果为None,则使用tempfile模块获取一个临时地址tempfile.gettempdir() # 如:/var/folders/d3/j9tj0gz93dg06bmwxmhh6_xm0000gn/T SESSION_COOKIE_NAME = "sessionid" # Session的cookie保存在浏览器上时的key,即:sessionid=随机字符串
SESSION_COOKIE_PATH = "/" # Session的cookie保存的路径
SESSION_COOKIE_DOMAIN = None # Session的cookie保存的域名
SESSION_COOKIE_SECURE = False # 是否Https传输cookie
SESSION_COOKIE_HTTPONLY = True # 是否Session的cookie只支持http传输
SESSION_COOKIE_AGE = 1209600 # Session的cookie失效日期(2周)
SESSION_EXPIRE_AT_BROWSER_CLOSE = False # 是否关闭浏览器使得Session过期
SESSION_SAVE_EVERY_REQUEST = False # 是否每次请求都保存Session,默认修改之后才保存

④缓存+数据库Session

#缓存+数据库Session
数据库用于做持久化,缓存用于提高效率,先去缓存中取数据,缓存没有再去数据库中取,然后在缓存中存一份 配置settings.py SESSION_ENGINE = 'django.contrib.sessions.backends.cached_db' # 引擎

⑤加密cookie Session

#加密cookie Session
数据都存在于客户端
配置settings.py SESSION_ENGINE = 'django.contrib.sessions.backends.signed_cookies' # 引擎
#注:当使用Session时,需要执行makemigrations和 migrate,数据库上会自动生成django_session数据表

Session&Cookie 总结

Cookie就是一段字符串,保存于本机电脑上。
session 保存于服务器,用来保存用户的会话信息,依赖于Cookies

流程:举个例子,咱们在登录一个网站后,拿JD举例,如果我登录进去之后,在想点击订单的时候。server断怎么判断我是“我”,而不是其他人呢?
Http是短连接,那么Server端肯定有一个保存我登录状态的地方(session),那server怎么判断是我发送过来的请求呢?就是通过Cookie!
当客户端访问过来后,server端会在IE里生成一个Cookie,当访问过来的时候就可以通过Cookie进行判断

在session中,我们可以设置多个key:value的值,我们可以在session设置,当用户登录的时候,我们把的用户名,增加到session中,那么用户携带cookie访问的时候,我们就能判断是哪个一用来访问的!

Session和Cookie好处:Cookie可以理解为一个身份证ID,你只能拿着他去和Server端进行通信,如果你没有这个ID那么server端也不知道你是谁!(我在写博客的时候在做Cookie和Session的实验,把Cookie删掉了!当我保存的时候直接给我提出来了,为什么呢?就是因为,server端不知道我是谁了,我已经没有密钥了。)

所以,只要Session和Cookie任意一方失效,就可以理解为:Cookie失效就相当于身份证ID过期,需要重新认证才可以继续使用。Session失效就相当于银行里的数据标识此ID无效,也需要重新申请。

最新文章

  1. c# ContinueWith 用法
  2. 【CentOS】正则表达式
  3. HTTP Header
  4. cxf spring restful 问题解决(jar包冲突)
  5. 用AngularJS开发的过程中如何查看Scope内容
  6. POJ 3259 Wormholes(SPFA)
  7. C++11 多线程 基础
  8. SDK文件夹下内容介绍
  9. 远程开发调试与hot-update | (R "think-of-lisper" 'Albertlee)
  10. poj 2689 巧妙地运用素数筛选
  11. python第一百零七天-- Django 基础 2
  12. find和grep命令合集
  13. 小程序里let和var以及const区别
  14. 面向对象【day08】:反射(五)
  15. 更改win系统的鼠标样式
  16. 关于Backbone和Underscore再说几点
  17. windows(64位)下使用curl命令
  18. iOS开发学习-类似微信聊天消息中的电话号码点击保存到通讯录中的功能
  19. Mysql学习---Python操作Mysql 1231
  20. html学习笔记--标签大全

热门文章

  1. Flink的Job启动JobManager端(源码分析)
  2. ZooKeeper异步调用命令
  3. 最简单流处理引擎——Kafka Streaming简介
  4. Apache JMeter HTTPS(S) Test Script Recorder
  5. 【HDU5409】CRB and Graph 边双联通 子树最值
  6. Problem : 这个题如果不是签到题 Asm.Def就女装(积性函数dp
  7. MPA JS CSS预处理方案
  8. AOE工程实践-NCNN组件
  9. 【Bit String Reordering UVALive - 6832 】【模拟】
  10. if __name__ = &quot;main&quot; 解释