Cookie是浏览器在客户端留下的一段记录,这段记录可以保留在内存或者硬盘上。因为Http请求是无状态的,通过读取cookie的记录,服务器或者客户端可以维持会话中的状态。比如一个常见的应用场景就是登录状态。Django里面,对cookie的读取和设置很简单。Cookie本身的格式类似字典,因此可以通过request的key或者get获取;然后他的设置则是通过response对象的set_cookie设定; 如果要取消cookie,把过期时间设置为当前时间就行了。
获取Cookie:
1
2
3
4
5
6
|
request.COOKIES[
'key'
]
request.get_signed_cookie(key, default
=
RAISE_ERROR, salt
=
'', max_age
=
None
)
参数:
default: 默认值
salt: 加密盐
max_age: 后台控制过期时间
|
设置Cookie:
1
2
3
4
5
6
7
8
9
10
11
12
13
|
rep
=
HttpResponse(...) 或 rep = render(request, ...)
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传输
httponly
=
False
只能http协议传输,无法被JavaScript获取(不是绝对,底层抓包可以获取到也可以被覆盖)
|
例1 设置一个login登录界面,一个index登录成功之后的跳转界面,如果没有登录那么自动跳转到登录界面
views.py
1
2
3
4
5
6
|
def
index(reqeust):
# 获取当前已经登录的用户
v
=
reqeust.COOKIES.get(
'username111'
)
if
not
v:
return
redirect(
'/login/'
)
return
render(reqeust,
'index.html'
,{
'current_user'
: v})
|
注意Cookie的超时时间有2种方式,一个是直接指定max_age(N秒后超时),一个是指定expires后面跟一个具体的时间对象
httponly可以禁止JavaScript获取这个值,但是实际上没有什么鸟用,chrome或者抓包都能轻松获取所有的cookie
index.html
1
2
3
4
5
6
7
8
9
10
|
<!DOCTYPE html>
<html lang
=
"en"
>
<head>
<meta charset
=
"UTF-8"
>
<title><
/
title>
<
/
head>
<body>
<h1>欢迎登录:{{ current_user }}<
/
h1>
<
/
body>
<
/
html>
|
login.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
<!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>
|
例2:
现实生活中,一般是把这个验证cookie的功能写成装饰器,这样直接在其他函数上面调用就行了板面
把例1改一下
1
2
3
4
5
6
7
8
9
10
11
12
13
|
def
auth(func):
def
inner(reqeust,
*
args,
*
*
kwargs):
v
=
reqeust.COOKIES.get(
'username111'
)
if
not
v:
return
redirect(
'/login/'
)
return
func(reqeust,
*
args,
*
*
kwargs)
return
inner
@auth
def
index(reqeust):
# 获取当前已经登录的用户
v
=
reqeust.COOKIES.get(
'username111'
)
return
render(reqeust,
'index.html'
,{
'current_user'
: v})
|
例3: 我们知道可以使用fbv或者cbv来路由函数。例2使用了fbv的方式,用cbv也能实现
cbv里面,如果只打算装饰一个方法,那么直接在方法前面加个@method_decorator就行;如果打算装饰这个类里面所有的方法,那么在整个类的最上面进行装饰
views.py
1
2
3
4
5
6
7
8
9
10
11
12
|
@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})
|
urls.py
1
|
url(r
'^order/'
, views.Order.as_view()),
|
例4 我们还可以通过JavaScript或者JQuery来设置Cookie,比如在前面分页的代码基础上,我们增加一个自定义显示行数的功能。
user_list.html 这里下了一个JQuery的插件,这样读取设置cookie比较容易;而且,我们还限制了cookie的使用范围,不是默认的所有范围,而是仅仅局限于/user_list这个路径里面
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
|
<!DOCTYPE html>
<
html
lang
=
"en"
>
<
head
>
<
meta
charset
=
"UTF-8"
>
<
title
></
title
>
<
style
>
.go{
width:20px;
border: solid 1px;
color: #66512c;
display: inline-block;
padding: 5px;
}
.pagination .page{
border: solid 1px;
color: #66512c;
display: inline-block;
padding: 5px;
papayawhip;
margin: 5px;
}
.pagination .page.active{
brown;
color: white;
}
</
style
>
</
head
>
<
body
>
<
ul
>
{% for item in li %}
{% include 'li.html' %}
{% endfor %}
</
ul
>
<
div
>
<
select
id
=
"ps"
onchange
=
"changePageSize(this)"
>
<
option
value
=
"10"
>10</
option
>
<
option
value
=
"30"
>30</
option
>
<
option
value
=
"50"
>50</
option
>
<
option
value
=
"100"
>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/`"});
console.log(v)
$('#ps').val(v);
});
function changePageSize(ths){
var v = $(ths).val();
console.log(v);
$.cookie('per_page_count',v, {'path': "/user_list/"});
location.reload();
}
</
script
>
</
body
>
</
html
>
|
views.py 从前端获取每页行数,实例化的时候传递给我们的分页类
1
2
3
4
5
6
7
8
9
10
|
def
user_list(request):
current_page
=
request.GET.get(
'p'
,
1
)
current_page
=
int
(current_page)
val
=
request.COOKIES.get(
'per_page_count'
,
10
)
val
=
int
(val)
page_obj
=
pagination.Page(current_page,
len
(
LIST
),val)
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})
|