定义:可以更快的读取数据的介质。一般用来存储临时数据,常用介质的是读取数据很快的内存。
缓存场景:
1、博客列表页
2、电商商品详情页
场景特点:缓存的地方,数据变动频率较少
当把一次负责查询的结果直接存储到表里,比如多个条件的过滤查询结果,可避免重复进行复杂查询,提升效率。
CACHES = {
'default':{
'BACKEND':'django.core.cache.backends.db.DatabaseCache',
'LOCATION':'my_cache_table',
'TIMEOUT':300, #缓存保存时间,单位秒,默认值300
'OPTIONS':{
'MAX_ENTRIES':300,#缓存最大数据条数
'CULL_FREQUENCY':2,#缓存条数达到最大值时,删除1/x的缓存数据
}
}
}
终端执行python manage.py createcachetable
方式1:视图函数
from django.views.decorators.cache import cache_page
@cache_page(30) # 单位s
def my_view(request):
pass
方式2:路由中
from django.views.decorators.cache import cache_page
urlpatterns = [
path('foo/',cache_page(60)(my_view))
]
引入cache对象
方式1:使用caches[‘CACHE’配置key’](适合有多个缓存配置项的情况)
from django.core.cache import caches
cache1 = caches['myalias']
方式2:from django.core.cache import cache
相当于直接引入CACHES配置项中的’default’项
缓存api的使用:
1、存储缓存:cache.set(key,value,timeout)
2、获取缓存:cache.get(key)
3、存储缓存:cache.add(key,value)
只在key不存在时生效
4、存储缓存:cache.get_or_set(key,value,value)
若未获取到,则执行set
5、批量存储缓存:cache.set_many(dict,value)
6、批量获取缓存:cache.get_many(key_list)
7、删除缓存:cache.delete(key)
8、批量删除缓存:cache.delete_many(key_list)
主要用于测试,使用频率不高
CACHES = {
'default':{
'BACKEND':'django.core.cache.backends.locmem.LocMemCache',
'LOCATION':'unique-snowflake',
}
缓存数据存储到本地文件中,不推荐用
CACHES = {
'default':{
'BACKEND':'django.core.cache.filebased.locmem.FileBasedCache',
'LOCATION':'文件夹路径',
}
cache装饰器可以自动给浏览器添加响应头。
此方法只根据时间判断,不够严谨,故常用后者
以类的形式体现,是Django请求/响应处理的钩子框架,是一个轻量级的、低级的“插件”系统,用于全局改变Django的输入输出。每一个中间件负责做一些特定的功能。
django.utils.deprecation.MiddlewareMixin
类process_request(self,request)
执行路由前被调用,在每个请求上调用,返回None或HttpResponse对象process_view(self,request,callback,callback_args,callback_kwargs)
调用视图函数前被调用,在每个请求上调用,返回None或HttpResponse对象process_response(self,request,response)
响应返回浏览器前被调用,在每个请求上调用,返回HttpResponse对象process_exception(self,request,exception)
当处理过程中抛出异常时调用,返回一个HttpResponse对象process_template_response(self,request,response)
在视图函数执行完毕且试图返回的对象中包含render的方法时被调用,需要返回实现了render方法的响应对象。1、settings.py中注册自定义的中间件MIDDLEWARE= ['middleware.mymiddleware.MyMW',]
2、在项目目录下创建middleware文件夹
3、编写mymiddleware.py
from django.utils.deprecation import MiddlewareMixin
class MyMW(MiddlewareMixin):
def process_request(self,request):
print('MyMW precess_request doing -- ')
def process_view(self,request,callback,callback_args,callback_kwargs):
print('MyMW process_view doing -- ')
def process_response(self,request,response):
print('MyMW process_response doing -- ')
return response
进入视图函数前,按照中间件注册顺序执行;在视图函数之后,中间件按照逆序调用的。
用中间件实现强制某个IP地址只能向/test开头的地址发送5次请求。
request.META['REMOTE_ADDR']
可以得到远程客户端的IP地址。
request.path_info
可以得到客户端访问的请求路由信息。
class VisitLimit(MiddlewareMixin):
visit_times={}
def process_request(self,request):
ip_address = request.META['REMOTE_ADDR']
path_url = request.path_info
if not re.match('^/test',path_url):
return None
times = self.visit_times.get(ip_address,0)
print('ip',ip_address,'已经访问',times)
self.visit_times[ip_address] = times + 1
return None if times < 5 else HttpResponse('您已经访问过'+str(times)+ '次,访问被禁止')
1、经历request中间件
2、urls / response中间件
3、经历view中间件
4、MTV层 / response中间件
5、有异常则经历exception异常捕获中间件 / response中间件
6、response中间件
某些恶意网站上包含链接、表单内容或JavaScript,他们会利用登陆过的用户在浏览器中的认证信息视图在你的网站上完成某些操作。
Django采用‘对比暗号’机制,Cookies中存储暗号1,模板中的表单里藏着暗号2,用户只有在本网站下提交数据,暗号2才会随表单提交给服务器,diango对比两个暗号,对比成功,则认为是合法请求,否则是违法请求403响应码。
配置:
MIDDLEWARE
中django.middleware.csrf.CsrfViewMiddleware
是否打开{%csrf_token%}
标签特殊说明:如果某个视图不需要csrf保护,可以用装饰器from django.views.decorators.csrf import csrf_exempt
web页面有大量数据需要显示,为了方便阅读在每个页中只显示部分数据。
Django使用django.core.paginator
模块的Paginator
类来管理分页数据。
paginator = Paginator(object_list,per_page)
paginator对象.page(number)
InvalidPage
异常page对象属性与方法:
分3页显示数组[‘a’,‘b’,‘c’,‘d’,‘e’]
def test_page(request):
# /test_page?page=4
page_num = request.GET.get('page',1)
all_data = ['a','b','c','d','e']
paginator = Paginator(all_data,2)
# 初始化具体页码的page对象
c_page = paginator.page(int(page_num))
return render(request,'test_page.html',locals())
<body>
{% for p in c_page %}
<p>
{{p}}
p>
{% endfor %}
{% if c_page.has_previous %}
<a href="/test_page?page={{ c_page.previous_page_number }}">上一页a>
{% else %}
上一页
{% endif %}
{% for p_num in paginator.page_range %}
{% if p_num == c_page.number %}
{{ p_num }}
{% else %}
<a href="/test_page?page={{p_num}}">{{p_num}}a>
{% endif %}
{% endfor %}
{% if c_page.has_next %}
<a href="/test_page?page={{ c_page.next_page_number }}">下一页a>
{% else %}
下一页
{% endif %}
body>
触发浏览器下载csv文件
import csv
with open('test_csv.csv','w',newline='') as csvfile:
writer = csv.writer(csvfile)
writer.writerow(['a','b','c'])
writer.writerow(['d','e'])
import csv
from django.http import HttpResponse
from .models import Book
def make_csv_view(request):
response = HttpResponse(content_type = 'text/csv')
response['Content-Disposition'] = 'attachment;filename="mybook.csv"'
all_book = Book.objects.all()
writer = csv.writer(response)
writer.writerow(['id','title'])
for b in all_book:
writer.writerow([b.id,b.title])
return response
练习:结合分页功能,在test_page页面添加‘生成csv’的链接,在指定页中点击该链接,生成当前页的csv数据,供用户下载。