django传递临时数据
把最近用到的临时数据传递总结下
有三种方法,cookie,session,cache
先说下对我来说会怎么选,cookie会用理解就行,我不常用,因为用户会关闭cookie,而且需要随着HttpResponse传递,有局限性
session的话也是,在配置时就不选择根据cookie,按照系统默认的数据库就好了
cache放到内存里,用起来方便也简单,就是占内存....,也可以放到库里,根据实际情况考虑吧
下面就是这三种方法的配置和使用了
一: cookie
- 获取cookie
HttpRequest.COOKIES
返回一个标准的字典
包含所有的cookie,键值都是str
- 存储cookie
HttpResponse.set_cookie(key, value='', max_age=None, expires=None, path='/', domain=None, secure=None, httponly=False)
max_age 以秒为单位设置保存的时长,当为None时,时长与客户端同步
domain 设置一个跨域的cookie
domain=".lawrence.com" 将设置一个www.lawrence.com、blogs.lawrence.com 和calendars.lawrence.com 都可读的Cookie。否则,Cookie 将只能被设置它的域读取。
可以写成domian=[],不会报错,但是没有测试是否真的可以跨站
httponly=False 当设置为True时阻止客户端的js读取cookie
- 删除操作
delete_cookie(key, path='/', domain=None)
删除key指定的cookie,当该cookie不存在时什么也不会发生
当set_cookie指定了path与domain时删除时应保持一致,否则不会删除
- 其他内容
因为是一个标准的字典,所以request.COOKIES['key']='value'也可以把内容放到cookie里,但是在传递给下个view的时候值就丢失了
在一个view中设置的cookie需要传递到下个view才能使用,如:
1 view1: 2 3 res = HttpResponseRedirect(revers("namespace:name") 4 5 res.set_cookie('key_set', 'value_set_view1', 60) 6 7 # 在这里是没办法获取不到现在的这个cookie 8 9 print(request.COOKIES) 10 11 # 直接设置COOKIES 12 13 COOKIES['key_dict'] = 'values_dict' 14 15 # 这里可以看到上面设置的内容 16 17 print(request.COOKIES) 18 19 return res 20 21 view2: 假设上面的Response就是指向这里的 22 23 print(request.COOKIES) 24 25 # 这里可以看到上面通过set设置的 key_set ,但是通过字典设置的key_dict就没有了
二: 使用session
在中间件插件集中添加django.contrib.sessions.middleware.SessionMiddleware
django1.10为 MIDDLEWARE,1.08为MIDDLEWARE_CLASSES
并且INSTALLED_APPS中应有'django.contrib.sessions'.
可以将session设置为基于cookie,文件,内存,数据库
- 基于数据库,将’django.contrib.sessions' 添加到INSTALLED_APPS中
在配置完成之后,运行manage.py migrate
- 基于文件设置SESSION_ENGINE为”django.contrib.sessions.backends.file"。
同时可以设置SESSION_FILE_PATH,来指定文件存放位置,否则使用系统默认的值,不修改就是/tmp
- 基于cookie的会话,不推荐,因为客户可以设置不使用cookie
设置SESSION_ENGINE 为"django.contrib.sessions.backends.signed_cookies"
- 基于缓存,当设置了缓存并设置缓存存放位置为内存时可以将会话设置为基于缓存的,只有缓存使用Memcached作为后端时才推荐这样
否则的话还不如直接使用缓存,灵活度更高,负载更小
SESSION_ENGINE 直接设置在setting.py的最外层即可
setting.py
SESSION_ENGINE = “django.contrib.sessions.backends.file"
- 使用会话
Session 的基类
backends.base.SessionBase
在view中获取session
request.session 获取一个标准的类字典
方法也与字典相同(不使用__私有方法)
session['fav_color'] = ‘blue' 设置会话
get(key, default=None)
例如:fav_color = request.session.get('fav_color', 'red')
pop(key)删除该键值对并返回值
例如:fav_color = request.session.pop('fav_color')
keys()
items()
setdefault(key[,default=None]) 当key存在时返回对应的值,不存在时将键值对添加到字典并返回默认的值
clear()
特殊方法
flush()
删除当前的会话数据并删除会话的Cookie。当用户注销时可以使用此操作
set_expiry(value) 设置会话超时时长
value可以设置为正整数,datatime/timedelta,0,None
整数(秒) n秒不操作则过期
datatime/timedelta 该时间点过期
0 关闭浏览器即过期
None 与全局默认值相同
get_expiry_age() 距离会话过期时长 当会话已过期或未自定义过期信息时返回None
关键字参数
odification:会话的最后一次修改时间,默认为当前 可以传递一个之前或之后的值,判断还有多久过期
expory 自定义的过期信息
get_expiry_date() 返回过期日期,已过期或未自定义返回cookie的保存时间
get_expire_at_browser_close()
返回True 或False,取决于用户的会话Cookie在用户浏览器关闭时会不会过期。
clear_expired() 类方法 从会话的存储中清除过期的会话。
cycle_key() 创建一个新的会话,同时保留当前的会话数据。
三: 使用缓存
- 设置缓存(使用内置的后台当内存足够且有必要时可以配置Memcached)
缓存在文件中
CACHES = {
'default': {
'BACKEND': 'django.core.cache.backends.filebased.FileBasedCache',
'LOCATION': ‘/var/tmp/django_cache', # 文件路径,当在win下改为’c:/tmp/django_cache'
}
}
路径是绝对路径,是一个目录,需要有当前用户的42(读写)权限
缓存在数据库中
CACHES = {
'default': {
'BACKEND': 'django.core.cache.backends.db.DatabaseCache',
'LOCATION': ‘my_cache_table', #表名,合法且未使用过即可
}
}
python manage.py createcachetable 创建缓存表,表名由LOCATION指定
缓存在内存中(默认情况)
CACHES = {
'default': {
'BACKEND': 'django.core.cache.backends.locmem.LocMemCache',
'LOCATION': ‘unique-snowflake', # 存储器 只有当有多个的时需要配置,只有一个内存就不用配置了
}
}
虚拟缓存:不缓存,但是保留接口用于确保开发生产环境的一致性
CACHES = {
'default': {
'BACKEND': 'django.core.cache.backends.dummy.DummyCache',
}
}
- 设置CACHES参数
TIMEOUT 超时时间默认300 即五分钟
VERSION 默认的缓存版本号
OPTIONS: 这个参数应该被传到缓存后端。有效的可选项列表根据缓存的后端不同而不同,由第三方库所支持的缓存将会把这些选项直接配置到底层的缓存库。
缓存的后端实现自己的选择策略 (文件,数据库,内存) 将会履行下面这些选项:
MAX_ENTRIES:高速缓存允许的最大条目数,超出这个数则旧值将被删除. 这个参数默认是300.
CULL_FREQUENCY:当达到MAX_ENTRIES 的时候,被删除的条目比率。 实际比率是 1 / CULL_FREQUENCY, 所以设置CULL_FREQUENCY 为2会在达到MAX_ENTRIES 所设置值时删去一半的缓存。这个参数应该是整数,默认为 3.
把 CULL_FREQUENCY的值设置为 0 意味着当达到MAX_ENTRIES时,缓存将被清空。某些缓存后端 (database尤其)这将以很多缓存丢失为代价.
实例:
缓存在内存中,且超时时长为60*10 600秒,缓存500条,每次删除1/5
CACHES = {
'default': {
'BACKEND': 'django.core.cache.backends.locmem.LocMemCache',
'TIMEOUT': 600,
'OPTIONS': {
'MAX_ENTRIES': 500,
'CULL_FREQUENCY': 5
}
}
}
- 缓存策略: 缓存整站, 缓存view, 缓存模板片段
- 缓存整站:
setting.py
1.08
MIDDLEWARE_CLASSES = (
'django.middleware.cache.UpdateCacheMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.cache.FetchFromCacheMiddleware',
)
1.10
MIDDLEWARE = [
'django.middleware.cache.UpdateCacheMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.cache.FetchFromCacheMiddleware',
]
注意顺序不要错
然后添加值在setting.py的最外层
CACHE_MIDDLEWARE_ALIAS – 用于存储的缓存的别名,不设置则为’default’
CACHE_MIDDLEWARE_SECONDS –每个page需要被缓存多少秒.
CACHE_MIDDLEWARE_KEY_PREFIX – 如果缓存被使用相同Django安装的多个网站所共享,那么把这个值设成当前网站名,或其他能代表这个Django实例的唯一字符串,以避免key发生冲突。 如果你不在意的话可以设成空字符串。
单个view缓存
from django.views.decorators.cache import cache_page
@cache_page(60 * 15)
def my_view(request):
pass
多个 URL 指向同一视图,每个URL将会分别缓存,如:
url(r'^foo/([0-9]{1,2})/$', my_view),
foo/12
foo/13 使用不同的缓存,但是两个12使用同一个
@cache_page(60 * 15, cache=“special_cache")
如: 将会只用指定的缓存
CACHES = {
'default': {
'BACKEND': 'django.core.cache.backends.locmem.LocMemCache',
'TIMEOUT': 600,
'OPTIONS': {
'MAX_ENTRIES': 500,
'CULL_FREQUENCY': 5
}
},
‘special_cache': {
'BACKEND': 'django.core.cache.backends.locmem.LocMemCache',
'TIMEOUT': 600,
'OPTIONS': {
'MAX_ENTRIES': 500,
'CULL_FREQUENCY': 5
}
}
}
在url中指定如何缓存
当需要访问/cache/与/nocache/时,同样指向一个页面,但是一个缓存一个不缓存
可以在url上指定哪个页面缓存,而不是在view上
url(r'^cache/$', cache_page(60 * 15)(my_view), name='cache'),
url(r’^nocache/$',my_view, name='nocache'),
模板缓存
{% load cache %}
{% cache 时长(秒) 名字 %}
{% endcache 名字 %}
更灵活的使用缓存
在views中导入 django.core.cache 的 caches
cad = caches[‘default’] # 这里的名字与CACHES中的配置一样
cas = caches[‘special_cache’]
常用的方法
cad.set(‘key’,’value’,时长) 不设时长则取默认值或自定义值
cad.get(‘key’) key 不存在返回None,也可以指定默认值get(‘key’,’默认值’),没有key则返回’默认值’
cad.add(‘key’,’value’) 当key不存在时增加key-value,当key已存在时不做操作,value还是之前的值
set_many({‘key1’:’v1’,’k2’:’v2’})
get_many([‘key1’,’key2’..]) 获取列表中的键的值 返回值为标准字典
delete(‘key’)
delete_many([‘key1’,’key2’]) 当key不存在时
clear() 删除全部缓存
close() 关闭缓存
cad.incr(‘key’,value) 相当于cad[‘key’]+=value 当然,只是相当于,不能这么做
由于底层使用的是new_value = value + delta
,那么.当value是’a’,也是可以的,只要是可以使用+的就可以
cad.decr(‘key’,value) 减 ,同上
缓存版本: VERSION 可以传入同样的键,却保存不一样的值,通过version来实现
cad.set(‘key1’,’valu’,version=3) 将key1设为version3,
ca.set('aa','dd',version=3)
ca.set(‘aa','e',version=4)
print(ca.get(‘aa’,version=3)) #=> dd
print(ca.get(‘aa’,version=4)) #=> e
incr_version(‘key’,value) 同样的,value支持+-即可
decr_version(‘key’,value)
但是不推荐直接使用str等,更不推荐使用自己的类
但当确实需要使用自定义的类来填充version时,需要重写的方法有(python3.x)
__str__
__add__
__sub__
参考:中文文档链接:缓存 http://python.usyiyi.cn/translate/django_182/topics/cache.html#django.views.decorators.cache.cache_page
会话 http://python.usyiyi.cn/translate/django_182/topics/http/sessions.html#module-django.contrib.sessions