一、CBV和FBV
FBV:functoin based view,基于函数的view
- 我们之前写过的都是基于函数的view
CBV:class based view,基于类的view
- 定义CBV:
from django.views import View class AddPublisher(View): def get(self,request): """处理get请求""" pass def post(self,request): """处理post请求""" pass
- 使用CBV:
url(r'^add_publisher/', views.AddPublisher.as_view())
as_view的流程
- 项目启动加载ur.py时,执行类.as_view() –> view函数
- 请求到来的时候执行view函数:
- 实例化类 –> self
- self.request = request
- 执行self.dispatch(request, *args, **kwargs)
- 判断请求方式是否被允许:
- 允许:通过反射获取到对应请求方式的方法 –> handler
- 不允许:self.http_method_not_allowed –> handler
- 执行handler(request,*args,**kwargs)
- 返回响应 –> 浏览器
- 判断请求方式是否被允许:
- 实例化类 –> self
二、视图加装饰器
装饰器示例:
def timer(func): def inner(request, *args, **kwargs): start = time.time() ret = func(request, *args, **kwargs) print("函数执行的时间是{}".format(time.time() - start)) return ret return inner
FBV
- 直接在函数上加装饰器
@timer def publisher_list(request): pass
CBV
- 导入
from django.utils.decorators import method_decorator
- 方法一:直接在方法上加装饰器
- 作用:只作用于加了装饰器的方法
@method_decorator(timer) def get(self, request, *args, **kwargs): pass
- 方法二:在dispatch方法上加装饰器
- 作用:作用于类里面的所有方法
@method_decorator(timer) def dispatch(self, request, *args, **kwargs): return super().dispatch(request, *args, **kwargs)
- 方法三:在类上加装饰器,要指定name,即要加装饰器的方法名
- 作用:只作用于name指定的方法
@method_decorator(timer,name='get') class AddPublisher(View): pass
- 特殊:等效于方法二,相当于给dispatch方法上了装饰器,作用于类里面的左右方法
@method_decorator(timer,name='dispatch') class AddPublisher(View): pass
类的方法上也可以直接用@timer,效果等同于使用@method_decorator(timer)
- 使用@timer和使用@method_decorator(timer)的区别:
- 使用@timer:
- 使用装饰器,取参数时【def inner(*args, **kwargs)】,第一个参数默认是self,第二个参数才是request对象
- 使用@method_decorator(timer):
- 使用装饰器,取参数时【def inner(*args, **kwargs)】,第一个参数就是request对象
- 使用@timer:
- 注意:之后取request对象做操作时,注意使用装饰器的方式,对应取request对象的方式也不同
- 使用@timer和使用@method_decorator(timer)的区别:
三、 request对象
属性:
- request.methot:当前请求方式,GET/POST
- request.GET:url上携带的参数
- request.POST:POST请求提交的数据
- request.path_info:url的路径,不包含ip和端口,不包含参数
- request.body:请求体,byte类型,request.POST的数据是从boby里提取的
- request.FILES:上传的文件,类似字典
- request.META:请求头,标准的Python字典,包含左右HTTP首部
- request.COOKIES:cookie
- request.session:session
方法:
- request.get_host():获取主机的ip和端口
- request.get_full_path():url的路径,不包含ip和端口,包含参数
- request.is_ajax():判断是否是ajax请求,是返回Ture,否返回False
上传文件示例:
- urls.py
url(r'^upload/', views.upload)
- views.py
def upload(request): if request.method == 'POST': # 获取文件 # print(request.FILES) f1 = request.FILES.get('f1') # 保存文件 with open(f1.name, 'wb') as f: for i in f1.chunks(): f.write(i) return render(request, 'upload.html')
- upload.html
<form action="" method="post" enctype="multipart/form-data"> {% csrf_token %} <input type="file" name="f1"> <button>上传</button> </form>
四、 response对象
Response对象:render, redirect, HttpResponse
from django.shortcuts import render, redirect, HttpResponse HttpResponse('字符串') # 返回字符串 render(request,'模板的文件名',{k1:v1}) # 返回一个完整的HTML页面 redirect('重定向的地址') # 返回重定向,Location:地址
JsonResponse对象
- 普通示例:
import json def json_data(request): data = {'name': 'alex', 'age': 73} return HttpResponse(json.dumps(data)) # Content-Type: text/html; charset=utf-8
- 使用JsonResponse对象示例:
from django.http.response import JsonResponse def json_data(request): data = {'name': 'alex', 'age': 73} return JsonResponse(data) # Content-Type: application/json
Content-Type:响应头
- Content-Type: application/json好处在于:告诉前端这是json类型,便于做相应操作
- 默认Content-Type: text/html; charset=utf-8,更改直接使用参数content_type=’application/json’
import json def json_data(request): data = {'name': 'alex', 'age': 73} return HttpResponse(json.dumps(data),content_type='application/json') # 此时,Content-Type: application/json
JsonResponse对象默认只能传递字典,对于非字典类型,设置参数safe=False
from django.http.response import JsonResponse def json_data(request): data = [1, 2, 3, 4] return JsonResponse(data,safe=False)