内置的版本控制类
from rest_framework.versioning import QueryParameterVersioning,AcceptHeaderVersioning,NamespaceVersioning,URLPathVersioning
基于url的get传参方式:QueryParameterVersioning 如:/user?version=v1
基于url的正则方式:URLPathVersioning /v1/user/
基于accept请求头方式:AcceptHeaderVersioning Accept:application/json;version=1
基于主机名方法:HostNameVersioning v1.example.com
基于django路由系统的namespace:NamespaceVersioning example.com/v1/users/
局部使用
在CBV类中加入
versioning_class = URLPathVersioning
全局使用
REST_FRAMEWORK = {'DEFAULT_VERSIONING_CLASS':'rest_framework.versioning.QueryParameterVersioning',
'DEFAULT_VERSION':'v1', 默认版本(request中无法取到)
'ALLOWED_VERSIONS':['v1','v2'], (允许的版本)
'VERSION_PARAM':'version'} URL中获取值的key
基于正则的方式:
from django.conf.urls import url,include
from web.views import TestView
urlpatterns = [ url(r'^(?P<version>[v1|v2]+)/test/',TestView.as_view(),name='test'),]
获取版本: request.version
获取版本管理的类: request.versioning_scheme
源码分析
执行determine_version,返回两个值,放到request对象里
version,scheme =self.determine_version(request,*args,**kwargs)
request.version,request.versioning_scheme = version,scheme
def determine_version(self,request,*args,**kwargs):
if self.versioning_class is None:
return (None,None)
scheme =self.versioning_class()
return (scheme.determine_version(request,*args,**kwargs),scheme)
django缓存
为了提高网站并发量
三种粒度;
全站缓存,单页面缓存,页面中布局缓存
6中缓存机制
django中使用缓存
第一步:在settings中配置(缓存方式),已缓存到文件举例
CACHE= {'default':{'BACKEND':'django.core.cache.backends.filebased.FileBaedCache',指定缓存使用的引擎
'LOCATION':'/var/tmp/django_cache', 指定缓存的路径
'TIMEOUT':300, 缓存超时时间(默认为300秒,None表示永不过期)
'OPTIONS':{'MAX_ENTRIES':300,'CULL_FREQUENCY':3,}}} 最大缓存的数量300, 缓存到达最大个数之后,剔除缓存个数的比例
第二部使用缓存
使用单页面缓存(使用装饰器):
from django.views.decorators.cache import cache_page
@cache_page(5)
def cache_test(request):
ctime = time.time()
return render(request,'index.html',locals())
页面局部缓存
{% load cache %}
第一个参数是超时时间,第二个参数是key值,唯一的标志
{% cache 5 'tt' %}
{{ ctime }}
{% endcache %}
全站缓存:配置中间件
配置两个中间件:
django.middleware.cache.UpdateCacheMiddleware'...
django.middleware.cache.FetchFromCacheMiddleware'
配置缓存时间
CACHE_MIDDLEWARE_SECONDS=10
缓存存储的数据格式
unique-snowflake={index:regre}
跨域问题
同源策略
浏览器基本的安全策略
当前页面只能朝当前域的地址发送请求
不同的域:ip+端口+协议 都相同才是同一个域
CORS 跨域资源共享
简单请求和非简单请求
只要符合以下两条,就是简单请求,否则就是费简单请求
(1):请求方法是以下三种之一
HEAD,GET,POST
(2):HTTP的头信息不超出以下几种字段:
Accept Accept-Language Content-Language Last-Event-ID
Content-Type:只限于三个值application/x-www-form-urlencoded,multipart/form-data,text.plain
简单请求只发一次请求
费简单请求发两次:一次是OPTIONS预检请求,预检通过再发第二次真实请求,
以后处理跨域问题(可以使用第三方的django-cors-headers):
写一个中间件:
class MyMiddleware(MiddlewareMixin):
def process_response(self,request,response):
response['Access-Control-Allow-origin']='*'
if request.method == 'OPTIONS':
response['Access-Control-Allow-Headers'] = '*'
response['Access-Control-Allow-Methods']="*"
return response
在settings中配置
redis
mysql,oracle:关系型数据库
redis,mongodb:菲关系型数据库/nosql
redis存储在内存内 mongodb存储到硬盘上
redis一般用来做:
做缓存
session数据
游戏排行榜
对速度要求比较高的数据的存储
做消息队列
redis是key-value的存储,支持持久化,类字典,有五大数据类型:
字符串:
列表:
字典:
集合:
有序集合:
redis = { k1:'123',字符串,可:[1,2,3]列表,k3:{1,2,3}集合,k4:{name:lqz,age:12}字典/hash表,k5:{('lqz',18),('egon',33)有序集合}}
比较redis和Memcached
redis支持五大数据类型 redis支持持久化,单进程,单线程,速度非常快
Memcached不能持久化,只支持字符串
python操作redis
安装redis模块
快速使用
import redis
conn = redis.Redis(host='127.0.0.1',port=6379)
name=conn.get('name')
redis连接池
首先新建模块
import redis
POOL = redis.ConnectionPool(host='127.0.0.1',port=6379.max_connections=1000)
使用连接池
from conn_pool import POOL
conn = redis.Redis(connection_pool=POOL)
Django中的6中缓存方式
开发者调试缓存
内存缓存
文件缓存
数据库缓存
Memcached缓存(使用python-memcache模块)
Memcache缓存(使用pylibmc模块)
1 CACHES = { 2 'default': { 3 'BACKEND': 'django.core.cache.backends.locmem.LocMemCache', # 指定缓存使用的引擎 4 'LOCATION': 'unique-snowflake', # 写在内存中的变量的唯一值 5 'TIMEOUT':300, # 缓存超时时间(默认为300秒,None表示永不过期) 6 'OPTIONS':{ 7 'MAX_ENTRIES': 300, # 最大缓存记录的数量(默认300) 8 'CULL_FREQUENCY': 3, # 缓存到达最大个数之后,剔除缓存个数的比例,即:1/CULL_FREQUENCY(默认3) 9 } 10 } 11 }
1 CACHES = { 2 'default': { 3 'BACKEND': 'django.core.cache.backends.filebased.FileBasedCache', #指定缓存使用的引擎 4 'LOCATION': '/var/tmp/django_cache', #指定缓存的路径 5 'TIMEOUT':300, #缓存超时时间(默认为300秒,None表示永不过期) 6 'OPTIONS':{ 7 'MAX_ENTRIES': 300, # 最大缓存记录的数量(默认300) 8 'CULL_FREQUENCY': 3, # 缓存到达最大个数之后,剔除缓存个数的比例,即:1/CULL_FREQUENCY(默认3) 9 } 10 } 11 }
1 CACHES = { 2 'default': { 3 'BACKEND': 'django.core.cache.backends.db.DatabaseCache', # 指定缓存使用的引擎 4 'LOCATION': 'cache_table', # 数据库表 5 'OPTIONS':{ 6 'MAX_ENTRIES': 300, # 最大缓存记录的数量(默认300) 7 'CULL_FREQUENCY': 3, # 缓存到达最大个数之后,剔除缓存个数的比例,即:1/CULL_FREQUENCY(默认3) 8 } 9 } 10 } 11 注意,创建缓存的数据库表使用的语句: 12 13 python manage.py createcachetable
Memcached是Django原生支持的缓存系统.要使用Memcached,需要下载Memcached的支持库python-memcached或pylibmc. settings.py文件配置 CACHES = { 'default': { 'BACKEND': 'django.core.cache.backends.memcached.MemcachedCache', # 指定缓存使用的引擎 'LOCATION': '192.168.10.100:11211', # 指定Memcache缓存服务器的IP地址和端口 'OPTIONS':{ 'MAX_ENTRIES': 300, # 最大缓存记录的数量(默认300) 'CULL_FREQUENCY': 3, # 缓存到达最大个数之后,剔除缓存个数的比例,即:1/CULL_FREQUENCY(默认3) } } } LOCATION也可以配置成如下: 'LOCATION': 'unix:/tmp/memcached.sock', # 指定局域网内的主机名加socket套接字为Memcache缓存服务器 'LOCATION': [ # 指定一台或多台其他主机ip地址加端口为Memcache缓存服务器 '192.168.10.100:11211', '192.168.10.101:11211', '192.168.10.102:11211', ]
1 视图: 2 3 复制代码 4 from django.views.decorators.cache import cache_page 5 import time 6 from .models import * 7 8 @cache_page(15) #超时时间为15秒 9 def index(request): 10 t=time.time() #获取当前时间 11 bookList=Book.objects.all() 12 return render(request,"index.html",locals()) 13 复制代码 14 模板(index.html): 15 16 复制代码 17 <!DOCTYPE html> 18 <html lang="en"> 19 <head> 20 <meta charset="UTF-8"> 21 <title>Title</title> 22 </head> 23 <body> 24 <h3>当前时间:-----{{ t }}</h3> 25 26 <ul> 27 {% for book in bookList %} 28 <li>{{ book.name }}--------->{{ book.price }}$</li> 29 {% endfor %} 30 </ul> 31 32 </body> 33 </html> 34 复制代码 35 上面的例子是基于内存的缓存配置,基于文件的缓存该怎么配置呢?? 36 37 更改settings.py的配置 38 39 复制代码 40 CACHES = { 41 'default': { 42 'BACKEND': 'django.core.cache.backends.filebased.FileBasedCache', # 指定缓存使用的引擎 43 'LOCATION': 'E:django_cache', # 指定缓存的路径 44 'TIMEOUT': 300, # 缓存超时时间(默认为300秒,None表示永不过期) 45 'OPTIONS': { 46 'MAX_ENTRIES': 300, # 最大缓存记录的数量(默认300) 47 'CULL_FREQUENCY': 3, # 缓存到达最大个数之后,剔除缓存个数的比例,即:1/CULL_FREQUENCY(默认3) 48 } 49 } 50 } 51 复制代码 52 然后再次刷新浏览器,可以看到在刚才配置的目录下生成的缓存文件 53 54 通过实验可以知道,Django会以自己的形式把缓存文件保存在配置文件中指定的目录中. 55 56 4.2 全站使用缓存 57 既然是全站缓存,当然要使用Django中的中间件. 58 59 用户的请求通过中间件,经过一系列的认证等操作,如果请求的内容在缓存中存在,则使用FetchFromCacheMiddleware获取内容并返回给用户 60 61 当返回给用户之前,判断缓存中是否已经存在,如果不存在,则UpdateCacheMiddleware会将缓存保存至Django的缓存之中,以实现全站缓存 62 63 复制代码 64 缓存整个站点,是最简单的缓存方法 65 66 在 MIDDLEWARE_CLASSES 中加入 “update” 和 “fetch” 中间件 67 MIDDLEWARE_CLASSES = ( 68 ‘django.middleware.cache.UpdateCacheMiddleware’, #第一 69 'django.middleware.common.CommonMiddleware', 70 ‘django.middleware.cache.FetchFromCacheMiddleware’, #最后 71 ) 72 “update” 必须配置在第一个 73 “fetch” 必须配置在最后一个 74 复制代码 75 修改settings.py配置文件 76 77 78 复制代码 79 MIDDLEWARE_CLASSES = ( 80 'django.middleware.cache.UpdateCacheMiddleware', #响应HttpResponse中设置几个headers 81 'django.contrib.sessions.middleware.SessionMiddleware', 82 'django.middleware.common.CommonMiddleware', 83 'django.middleware.csrf.CsrfViewMiddleware', 84 'django.contrib.auth.middleware.AuthenticationMiddleware', 85 'django.contrib.auth.middleware.SessionAuthenticationMiddleware', 86 'django.contrib.messages.middleware.MessageMiddleware', 87 'django.middleware.clickjacking.XFrameOptionsMiddleware', 88 'django.middleware.security.SecurityMiddleware', 89 'django.middleware.cache.FetchFromCacheMiddleware', #用来缓存通过GET和HEAD方法获取的状态码为200的响应 90 91 ) 92 93 94 CACHE_MIDDLEWARE_SECONDS=10 95 复制代码 96 视图函数: 97 98 复制代码 99 from django.views.decorators.cache import cache_page 100 import time 101 from .models import * 102 103 104 def index(request): 105 106 t=time.time() #获取当前时间 107 bookList=Book.objects.all() 108 return render(request,"index.html",locals()) 109 110 def foo(request): 111 t=time.time() #获取当前时间 112 return HttpResponse("HELLO:"+str(t)) 113 复制代码 114 模板(index.html): 115 116 复制代码 117 <!DOCTYPE html> 118 <html lang="en"> 119 <head> 120 <meta charset="UTF-8"> 121 <title>Title</title> 122 </head> 123 <body> 124 <h3 style="color: green">当前时间:-----{{ t }}</h3> 125 126 <ul> 127 {% for book in bookList %} 128 <li>{{ book.name }}--------->{{ book.price }}$</li> 129 {% endfor %} 130 </ul> 131 132 </body> 133 </html> 134 复制代码 135 其余代码不变,刷新浏览器是10秒,页面上的时间变化一次,这样就实现了全站缓存. 136 137 4.3局部视图缓存 138 例子,刷新页面时,整个网页有一部分实现缓存 139 140 views视图函数 141 142 复制代码 143 from django.views.decorators.cache import cache_page 144 import time 145 from .models import * 146 def index(request): 147 t=time.time() #获取当前时间 148 bookList=Book.objects.all() 149 return render(request,"index.html",locals()) 150 复制代码 151 模板(index.html): 152 153 复制代码 154 {% load cache %} 155 <!DOCTYPE html> 156 <html lang="en"> 157 <head> 158 <meta charset="UTF-8"> 159 <title>Title</title> 160 </head> 161 <body> 162 <h3 style="color: green">不缓存:-----{{ t }}</h3> 163 164 {% cache 2 'name' %} 165 <h3>缓存:-----:{{ t }}</h3> 166 {% endcache %} 167 168 </body> 169 </html>
1 string操作,redis中的string在内存中按照一个name对应一个value来存储 2 setname,value,ex=None,px=False,xx=False) 3 在Redis中设置值,默认,不存在则创建,存在则修改 4 参数: 5 ex:过期时间(秒) 6 px:过期时间(毫秒) 7 nx:如果设置为True,则只有name不存在时,当前set操作才执行,只存在就修改不了,执行没效果 8 xx:如果设置为True,则只有name存在时,当前set操作才执行,值存在才能修改,值不存在不会设置新值 9 setnx(name,value) 10 设置值,只有name不存在时,执行设置操作(添加),如果存在,不会修改 11 setex(name,value,time) 12 设置值,参数:time过期时间(数字秒,或timedelta对象) 13 psetex(name,time_ms,value) 14 设置值 参数:time_ms过期时间(数字毫秒) 15 mset(*args,**kwargs) 16 批量设置值 如:mset(k1='v1',k2='v2')或mget({'k1':'v1','k2':'v2'}) 17 get(name) 18 获取值 19 mget(key,*args) 20 批量获取 mget('k1','k2') 或 mget(['k3','k4']) 21 getset(name,value) 22 设置新值并获取原来的值 23 getrange(key,start,end) 24 获取子序列(根据字节获取,非字符) 25 参数:start:起始位置 end 结束位置 26 setrange(name, offset, value) 27 28 # 修改字符串内容,从指定字符串索引开始向后替换(新值太长时,则向后添加) 29 # 参数: 30 # offset,字符串的索引,字节(一个汉字三个字节) 31 # value,要设置的值 32 strlen(name) 33 34 # 返回name对应值的字节长度(一个汉字3个字节) 35 incr(self, name, amount=1) 36 37 复制代码 38 # 自增 name对应的值,当name不存在时,则创建name=amount,否则,则自增。 39 40 # 参数: 41 # name,Redis的name 42 # amount,自增数(必须是整数) 43 44 # 注:同incrby 45 复制代码 46 incrbyfloat(self, name, amount=1.0) 47 48 # 自增 name对应的值,当name不存在时,则创建name=amount,否则,则自增。 49 50 # 参数: 51 # name,Redis的name 52 # amount,自增数(浮点型) 53 decr(self, name, amount=1) 54 55 # 自减 name对应的值,当name不存在时,则创建name=amount,否则,则自减。 56 57 # 参数: 58 # name,Redis的name 59 # amount,自减数(整数) 60 append(key, value) 61 62 63 64 # 在redis name对应的值后面追加内容 65 66 # 参数: 67 key, redis的name 68 value, 要追加的字符串