12.4 Cookie和Session

12.41 cookie

Cookie具体指的是一段小信息,它是服务器发送出来存储在浏览器上的一组组键值对,下次访问服务器时浏览器会自动携带这些键值对,以便服务器提取有用信息

获取Cookie:

request.COOKIES['login']                           #找不到时报错
login_flag = request.COOKIES.get("login","") #找不到时返回None
request.get_signed_cookie(key, default=RAISE_ERROR, salt='', max_age=None)
login_flag = request.get_signed_cookie("login",default="",salt="shanghais1hao")#找不到时返回默认值空

设置Cookie:给HttpResponse、render、redirect实例化的对象设置cookie

rep = HttpResponse("xxxx")
rep = render(request, "book_list.html")
rep = redirect('/book_list/')

rep.set_cookie(key,value,...)
rep.set_signed_cookie(key,value,salt='加密盐', max_age=None, ...)
rep.set_signed_cookie("login", "ok", salt="shanghais1hao", max_age=None)

删除Cookie:给HttpResponse、render、redirect实例化的对象删除cookie

def logout(request):
rep = redirect("/login/")
rep.delete_cookie("login") # 删除用户浏览器上之前设置的cookie值
return rep

12.42 Session

Cookie弥补了HTTP无状态的不足,让服务器知道来的人是“谁”;但是Cookie以文本的形式保存在本地,自身安全性较差;所以通过Cookie识别不同的用户,对应的在Session里保存私密的信息以及超过4096字节的文本

获取Session

request.session['k1']
request.session.get('k1',None)
login_flag = request.session.get("login")

设置Session

request.session['k1'] = 123
request.session.setdefault('k1',123) # 存在则不设置,不存在则设置
request.session["login"] = "OK"
request.session["user"] = username

删除Session

def logout(request):
request.session.flush()
#删除当前的会话session数据并删除会话的Cookie,这用于确保前面的会话数据不可以再次被用户的浏览器访问
request.session.delete() # 删除当前会话的所有Session数据
return redirect("/login/")

del request.session['login']

所有 键、值、键值对:

request.session.keys()      #dict_keys(['login', 'user', '_session_expiry'])
request.session.values() #dict_values(['OK', 'alex', 1209600])
request.session.items() #dict_items([('login', 'OK'), ('user', 'alex'), ('_session_expiry', 1209600)])
request.session.iterkeys()
request.session.itervalues()
request.session.iteritems()

其他session的属性和方法:

# 会话session的key
request.session.session_key #k69mo6fu6qmvq7hpapdy54erpce1ksy5
# 将所有Session当前日期大于失效日期的数据删除
request.session.clear_expired()
# 检查会话session的key在数据库中是否存在
request.session.exists("session_key")
# 设置会话Session和Cookie的超时时间
request.session.set_expiry(value)
* 如果value是个整数,session会在数秒数后失效。
* 如果value是个datatime或timedelta,session就会在这个时间后失效。
* 如果value是0,用户关闭浏览器session就会失效。
* 如果value是None,session会依赖全局session失效策略。
request.session.set_expiry(60 * 60 * 24 * 14)
12.421 Django中的Session配置(settings.py)
1. 数据库Session
SESSION_ENGINE = 'django.contrib.sessions.backends.db' # 引擎(默认)

2. 缓存Session
SESSION_ENGINE = 'django.contrib.sessions.backends.cache' # 引擎
SESSION_CACHE_ALIAS = 'default' # 使用的缓存别名(默认内存缓存,也可以是memcache),此处别名依赖缓存的设置

3. 文件Session
SESSION_ENGINE = 'django.contrib.sessions.backends.file' # 引擎
SESSION_FILE_PATH = None # 缓存文件路径,如果为None,则使用tempfile模块获取一个临时地址tempfile.gettempdir()

4. 缓存+数据库
SESSION_ENGINE = 'django.contrib.sessions.backends.cached_db' # 引擎

5. 加密Cookie Session
SESSION_ENGINE = 'django.contrib.sessions.backends.signed_cookies' # 引擎

其他公用设置项:
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,默认修改之后才保存(默认)

12.5 Django中间件

中间件:在视图函数执行之前和执行之后都可以做一些额外的操作,它本质上就是一个自定义类,类中定义了几个方法,Django框架会在请求的特定的时间去执行这些方法。

process_request(self,request)
process_view(self, request, view_func, view_args, view_kwargs)
process_template_response(self,request,response)
process_exception(self, request, exception)
process_response(self, request, response)

以上方法的返回值可以是None或一个HttpResponse对象,如果是None,则继续按照django定义的规则向后继续执行,如果是HttpResponse对象,则直接将该对象返回给用户

自定义一个中间件示例:

from django.utils.deprecation import MiddlewareMixin

class MD1(MiddlewareMixin):
def process_request(self, request):
print("MD1里面的 process_request")
def process_response(self, request, response):
print("MD1里面的 process_response")
return response

12.51 中间件版登录验证

中间件版的登录验证需要依靠session,所以数据库中要有django_session表

middlewares.py:

class AuthMD(MiddlewareMixin):
white_list = ['/login/', ] # 白名单
balck_list = ['/black/', ] # 黑名单

def process_request(self, request):
from django.shortcuts import redirect, HttpResponse

next_url = request.path_info
#print(request.path_info, request.get_full_path())
if next_url in self.white_list or request.session.get("user"):
return
elif next_url in self.balck_list:
return HttpResponse('This is an illegal URL')
else:
return redirect("/login/?next={}".format(next_url))

在settings.py中注册:

MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'middlewares.AuthMD',
]

urls.py:

from django.conf.urls import url
from app01 import views

urlpatterns = [
url(r'^index/$', views.index),
url(r'^login/$', views.login, name='login'),
]

views.py:

from django.shortcuts import render, HttpResponse, redirect
def index(request):
return HttpResponse('this is index')

def home(request):
return HttpResponse('this is home')

def login(request):
if request.method == "POST":
user = request.POST.get("user")
pwd = request.POST.get("pwd")

if user == "Q1mi" and pwd == "":
request.session["user"] = user# 设置session
next_url = request.GET.get("next") # 获取跳到登陆页面之前的URL
if next_url:
return redirect(next_url)# 如果有,就跳转回登陆之前的URL
else:
return redirect("/index/") # 否则默认跳转到index页面
return render(request, "login.html")

login.html:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="x-ua-compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>登录页面</title>
</head>
<body>
<form action="{% url 'login' %}">
<p>
<label for="user">用户名:</label>
<input type="text" name="user" id="user">
</p>
<p>
<label for="pwd">密 码:</label>
<input type="text" name="pwd" id="pwd">
</p>
<input type="submit" value="登录">
</form>
</body>
</html>

12.6 AJAX

AJAX(Asynchronous Javascript And XML)翻译成中文就是“异步的Javascript和XML”。即使用Javascript语言与服务器进行异步交互,传输的数据为XML(当然,传输的数据不只是XML)。AJAX 不是新的编程语言,而是一种使用现有标准的新方法。

AJAX 最大的优点是在不重新加载整个页面的情况下,可以与服务器交换数据并更新部分网页内容。(这一特点给用户的感受是在不知不觉中完成请求和响应过程)

AJAX 不需要任何浏览器插件,但需要用户允许JavaScript在浏览器上执行。

  • 同步交互:客户端发出一个请求后,需要等待服务器响应结束后,才能发出第二个请求;

  • 异步交互:客户端发出一个请求后,无需等待服务器响应结束,就可以发出第二个请求。

AJAX优点:

  • AJAX使用JavaScript技术向服务器发送异步请求;

  • AJAX请求无须刷新整个页面;

  • 因为服务器响应内容不再是整个页面,而是页面中的部分内容,所以AJAX性能高;

页面输入两个整数,通过AJAX传输到后端计算出结果并返回:

urls.py:

urlpatterns = [
...
url(r'^ajax_add/', views.ajax_add),
url(r'^ajax_demo1/', views.ajax_demo1),
...
]

views.py:

def ajax_demo1(request):
return render(request, "ajax_demo1.html")

def ajax_add(request):
i1 = int(request.GET.get("i1"))
i2 = int(request.GET.get("i2"))
ret = i1 + i2
return JsonResponse(ret, safe=False)

ajax_demo1.html:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="x-ua-compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>AJAX局部刷新实例</title>
</head>
<body>
<input type="text" id="i1">+
<input type="text" id="i2">=
<input type="text" id="i3">
<input type="button" value="AJAX提交" id="b1">
<script src="/static/jquery-3.2.1.min.js"></script>
<script>
$("#b1").on("click", function () {
$.ajax({
url:"/ajax_add/", #往哪里发送请求
type:"GET", #请求的方法
data:{"i1":$("#i1").val(),"i2":$("#i2").val()},#发送到后端的请求数据
success:function (data) { #请求被正常响应时自动执行的回调函数
$("#i3").val(data);
}
})
})
</script>
</body>
</html>

12.61AJAX请求设置csrf_token

方式一:通过获取隐藏的input标签中的csrfmiddlewaretoken值,放置在data中发送

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="x-ua-compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>AJAX局部刷新实例</title>
</head>
<body>
{% csrf_token %}
<input type="text" id="i1">+
<input type="text" id="i2">=
<input type="text" id="i3">
<input type="button" value="AJAX提交" id="b1">
<script src="/static/jquery-3.2.1.min.js"></script>
<script>
$("#b1").on("click", function () {
$.ajax({
url: "/cookie_ajax/",
type: "POST",
data: {"i1":$("#i1").val(),"i2":$("#i2").val(),"csrfmiddlewaretoken": $("[name = 'csrfmiddlewaretoken']").val() // 使用jQuery取出csrfmiddlewaretoken的值,拼接到data中
},
success: function (data) {
console.log(data);
}
})
})
</script>
</body>
</html>

方式二:通过获取返回的cookie中的字符串,放置在请求头中发送。注意:需要引入一个jquery.cookie.js插件。

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="x-ua-compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>AJAX局部刷新实例</title>
</head>
<body>
<input type="text" id="i1">+
<input type="text" id="i2">=
<input type="text" id="i3">
<input type="button" value="AJAX提交" id="b1">
<script src="/static/jquery-3.2.1.min.js"></script>
<script>
$("#b1").on("click", function () {
$.ajax({
url: "/cookie_ajax/",
type: "POST",
headers: {"X-CSRFToken": $.cookie('csrftoken')}, # 从Cookie取csrftoken,并设置到请求头中
data: {"i1":$("#i1").val(),"i2":$("#i2").val()},
success: function (data) {
console.log(data);
}
})
})
</script>
</body>
</html>

或者自己写一个getCookie方法:

function getCookie(name) {
var cookieValue = null;
if (document.cookie && document.cookie !== '') {
var cookies = document.cookie.split(';');
for (var i = 0; i < cookies.length; i++) {
var cookie = jQuery.trim(cookies[i]);
# Does this cookie string begin with the name we want?
if (cookie.substring(0, name.length + 1) === (name + '=')) {
cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
break;
}
}
}
return cookieValue;
}
var csrftoken = getCookie('csrftoken');

12.62 Django序列化

from app01 import models
def persons(request):
ret = models.Person.objects.all()
#re=models.Person.objects.all().values_list('data')
# import json
# person_list = []
# for i in ret:
# person_list.append({"name": i.name, "age": i.age})
# s = json.dumps(person_list)
from django.core import serializers
s = serializers.serialize("json", ret) #序列化对象,取出对象所有属性组成字典并序列化成json字符串
#s = serializers.serialize("json", ret) 序列化日期类型
return HttpResponse(s)

12.63 AJAX上传文件

formData的基本用法:FormData对象,可以把所有表单元素的name与value组成一个queryString,提交到后台。只需要把 form 表单作为参数传入 FormData 构造函数即可

利用 FormData 来上传文件:

#上传文件示例
<body>
<div>
<input accept="image/*" type="file" name="avatar" id="f1">
<input type="button" value="提交" id="b1">
</div>
<script src="/static/jquery-3.3.1.min.js"></script>
<script>
$("#b1").click(function () {
var formData = new FormData(); #生成一个FormData对象
formData.append("csrfmiddlewaretoken", $("[name='csrfmiddlewaretoken']").val());
formData.append("f1", $("#f1")[0].files[0]);#得到用户选中的文件对象,并向formData对象中添加键值对数据
$.ajax({
url: "/upload/",
type: "POST",
processData: false, #告诉jQuery不要去处理发送的数据
contentType: false, #告诉jQuery不要去设置Content-Type请求头
data: formData,
success:function (data) { #请求被正常响应时自动执行的回调函数
console.log(data)
}
})
})
</script>
</body>

或者:

var form = document.getElementById("form1");
var fd = new FormData(form);

这样也可以直接通过ajax 的 send() 方法将 fd 发送到后台。

注意:由于 FormData 是 XMLHttpRequest Level 2 新增的接口,现在 低于IE10 的IE浏览器不支持 FormData。

views.py:

from django.shortcuts import render, HttpResponse
from django.http import JsonResponse

def upload(request):
if request.method == "POST":
file_obj = request.FILES.get("avatar") # 获取文件对象
with open(file_obj.name, "wb") as f: # file_obj.name --> 上传文件的文件名
for chunk in file_obj.chunks(): # 从该文件对象里一点一点读取数据,写入刚新建的文件句柄f
f.write(chunk)
# return JsonResponse("OK",safe=False)
return HttpResponse("OK")
return render(request, "upload.html")

Python 之 Django框架( Cookie和Session、Django中间件、AJAX、Django序列化)的更多相关文章

  1. Django之cookie与session、中间件

    目录 cookie与session 为什么会有cookie和session cookie 设置cookie 获取cookie 删除cookie 实例:cookie版登录校验 session 设置ses ...

  2. Django之Cookie、Session、CSRF、Admin

    Django之Cookie.Session.CSRF.Admin   Cookie 1.获取Cookie: 1 2 3 4 5 6 request.COOKIES['key'] request.get ...

  3. [py][mx]django的cookie和session操作-7天免登录

    浏览器同源策略(same-origin policy) csrf攻击防御核心点总结 django的cookie和session操作-7天免登录 flask操作cookie&django的see ...

  4. Django --- cookie与session,中间件

    目录 1.cookie与session 1.cookie 2.session 2.中间件 1.中间件作用 2.用户可以自定义的五个方法 3.自定义中间件 1.cookie与session 1.cook ...

  5. Django基础cookie和session

    Django基础cookie和session 1.会话跟踪 ​ 什么是会话!可以把会话理解为客户端与服务器之间的一次会晤,在一次会晤中可能会包含多次请求和响应.例如给10086打个电话,你就是客户端, ...

  6. Django框架 之 Form表单和Ajax上传文件

    Django框架 之 Form表单和Ajax上传文件 浏览目录 Form表单上传文件 Ajax上传文件 伪造Ajax上传文件 Form表单上传文件 html 1 2 3 4 5 6 7 <h3& ...

  7. web框架开发-Django组件cookie与session

    http协议的每一次都是无保存状态的请求,这会带来很多的不方便,比如,一刷新网页,或者进入该网页的其他页面,无法保存之前的登录状态.为了解决类似这样的问题,引入了会话跟踪 会话跟踪技术 1 什么是会话 ...

  8. django框架--cookie/session

    目录 一.http协议无状态问题 二.会话跟踪技术--cookie 1.对cookie的理解 2.cookie的使用接口 3.cookie的属性 4.使用cookie的问题 三.会话跟踪技术--ses ...

  9. pyhton框架Django之cookie和session

    一,cookie和session的理解 cookies 是浏览器为 Web 服务器存储的一小段信息. 每次浏览器从某个服务器请求页面时,它向服务器回送之前收到的cookies.它保存在浏览器下的某个文 ...

  10. django的cookie和session以及内置信号、缓存

    cookie和session cookie和session的作用: cookie和session都记录了客户端的某种状态,用来跟踪用户访问网站的整个回话.两者最大的区别是cookie的信息是存放在浏览 ...

随机推荐

  1. Java设计模式(一) 简单工厂模式不简单

    摘要:本文介绍了简单工厂模式的概念,优缺点,实现方式,以及结合Annotation和反射的改良方案(让简单工厂模式不简单).同时介绍了简单工厂模式(未)遵循的OOP原则.最后给出了简单工厂模式在JDB ...

  2. 关于spring boot jar包与war包的问题

    此文为转载:http://mrlee23.iteye.com/blog/2047968 在开发调试完成之后,可以将应用打成JAR包的形式,在Eclipse中可以直接使用Maven插件的package命 ...

  3. Condition

    1.Condition是个接口,其实现类是同步器里面的一个内部静态类:ConditionObject. 2.Lock是个接口,该接口里面有个方法是:Condition newCondition(); ...

  4. Entity Framework 不支持DefaultValue

    http://stackoverflow.com/questions/18506088/entityframework-not-updating-column-with-default-value Y ...

  5. Yeoman+Express+Angular在Linux上开发配置方法

    $mkdir ExpressWithAngularTest $cd ExpressWithAngularTest choose needed components you'd like to add ...

  6. 【转载】nginx 并发数问题思考:worker_connections,worker_processes与 max clients

    注:这个文章主要是作者一直在研究nginx作为http server和反向代理服务器时候所谓最大的max_clients和 worker_connections的计算公式, 其实最后的结论也没有卡上公 ...

  7. innodb部分参数优化

    参数调优内容:1. 内存利用方面2. 日值控制方面3. 文件IO分配,空间占用方面4. 其它相关参数 1.内存利用方面:首先介绍一个Innodb最重要的参数:innodb_buffer_pool_si ...

  8. Unix/Linux环境C编程入门教程(31) 数学函数带你战胜企业面试

    1.函数介绍: abs()acos()asin()atan()atan2()ceil()cos()cosh()exp()frexp()ldexp()log()log10()pow()sin()sinh ...

  9. Linux之第一个shell命令

    今天在学习shell脚本的编写,网上看了一个helloworld的栗子: #!/bin/sh #print hello world in the console window a = "he ...

  10. 循环语句--do...while

    do...while循环 格式: 执行流程 执行顺序:①③④>②③④>②③④…②不满足为止. ①负责完成循环变量初始化. ②负责判断是否满足循环条件,不满足则跳出循环. ③具体执行的语句 ...