一、模板语言 

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无效,也需要重新申请。

Python学习笔记整理总结【Django】:模板语言、分页、Cookie、Session的更多相关文章

  1. python学习笔记整理——字典

    python学习笔记整理 数据结构--字典 无序的 {键:值} 对集合 用于查询的方法 len(d) Return the number of items in the dictionary d. 返 ...

  2. python 学习笔记十六 django深入学习一 路由系统,模板,admin,数据库操作

    django 请求流程图 django 路由系统 在django中我们可以通过定义urls,让不同的url路由到不同的处理函数 from . import views urlpatterns = [ ...

  3. Python学习笔记整理总结【Django】【MVC/MTV/路由分配系统(URL)/视图函数 (views)/表单交互】

     一.Web框架概述  Web框架本质上其实就是一个socket服务端,用户的浏览器其实就是一个socket客户端. #!/usr/bin/env python # -*- coding:utf-8 ...

  4. Python学习笔记整理总结【Django】:Model操作(一)

    Model操作(一) 一.Django ORM基本配置 ORM:关系对象映射(Object Relational Mapping,简称ORM)db Frist:到目前为止,当我们的程序涉及到数据库相关 ...

  5. python 学习笔记十八 django深入学习三 分页,自定义标签,权限机制

    django  Pagination(分页) django 自带的分页功能非常强大,我们来看一个简单的练习示例: #导入Paginator>>> from django.core.p ...

  6. python学习笔记整理——集合 set

    python学习整理笔记--集合 set 集合的用途:成员测试和消除重复的条目,进行集合运算 注意:花括号或set()函数可以用于创建集合. 注意:若要创建一个空的集合你必须使用set(),不能用{} ...

  7. python 学习笔记二十 django项目bbs论坛

    项目:开发一个简单的BBS论坛 需求: 整体参考“抽屉新热榜” + “虎嗅网” 实现不同论坛版块 帖子列表展示 帖子评论数.点赞数展示 在线用户展示 允许登录用户发贴.评论.点赞 允许上传文件 帖子可 ...

  8. python 学习笔记十五 django基础

    Python的WEB框架有Django.Tornado.Flask 等多种,Django相较与其他WEB框架其优势为:大而全,框架本身集成了ORM.模型绑定.模板引擎.缓存.Session等诸多功能. ...

  9. python学习笔记整理——元组tuple

    Python 文档学习笔记2 数据结构--元组和序列 元组 元组在输出时总是有括号的 元组输入时可能没有括号 元组是不可变的 通过分拆(参阅本节后面的内容)或索引访问(如果是namedtuples,甚 ...

随机推荐

  1. React生命周期函数理解

    一.组件挂载阶段 1. componentWillMount() 该方法在首次渲染之前调用,在一个组件挂载到卸载的过程中,仅仅执行这一次.该函数内可以state初始化的工作,与constructor的 ...

  2. Win10下安装python3.x+pycharm+autopep8

    一.安装Python3.X 1.Pythong官方网站:http://python.org/getit/   下载windows的安装包.有以下几个选项: 这里选择windows x86-64 exc ...

  3. Java8新特性_lambda表达式和函数式接口最详细的介绍

    Lambda表达式 在说Lambda表达式之前我们了解一下函数式编程思想,在数学中,函数就是有输入量.输出量的一套计算方案,也就是“拿什么东西做什么事情”. 相对而言,面向对象过分强调“必须通过对象的 ...

  4. 使用element-ui中table expand展开行控制显示隐藏

    问题讲解:在使用vue版本的ElementUI中的table功能的时候还是遇到了一些问题,可以说饿了么团队在这个UI框架的文档撰写已经非常不错了,不过还是有一些方法乍一看让人摸不着头脑,有些table ...

  5. SCRUM的三个工件

    转自:http://www.scrumcn.com/agile/scrum-knowledge-library/scrum.html#tab-id-6 Scrum 的工件以不同的方式展现工作和价值,可 ...

  6. [python]python列表、元组

    1. 列表和元组简介 列表:用中括号[]包裹,元素的个数及元素的值可以改变. 元组:用小括号()包裹,不可用更改. 通过切片运算[]和[:]可以得到子集. 2.列表 示例: List = [1, 2, ...

  7. P2746 [USACO5.3]校园网Network of Schools tarjan 缩点

    题意 给出一个有向图,A任务:求最少需要从几个点送入信息,使得信息可以通过有向图走遍每一个点B任务:求最少需要加入几条边,使得有向图是一个强联通分量 思路 任务A,比较好想,可以通过tarjan缩点, ...

  8. ACM-ICPC 2018 沈阳赛区(网络赛)

    D.Made In Heaven One day in the jail, F·F invites Jolyne Kujo (JOJO in brief) to play tennis with he ...

  9. codeforces 862 C. Mahmoud and Ehab and the xor(构造)

    题目链接:http://codeforces.com/contest/862/problem/C 题解:一道简单的构造题,一般构造题差不多都考自己脑补,脑洞一开就过了 由于数据x只有1e5,但是要求是 ...

  10. codeforces 822 D. My pretty girl Noora(dp+素数筛)

    题目链接:http://codeforces.com/contest/822/problem/D 题解:做这题首先要推倒一下f(x)假设第各个阶段分成d1,d2,d3...di组取任意一组来说,如果第 ...