VIEW 视图
FBV CBV
Django中请求处理方式有两种: FBV和CBV
FBV: function base views 在试图里使用函数处理请求
# url对应关系:url(r'^add_publisher/', views.add_publisher), from django.views import View def add_publisher(request): '''新增出版社数据''' if request.method == 'POST': # 获取提交的数据(括号内为input的name属性值),没有默认空字符串 new_name = request.POST.get('new_name','').strip() # 设定输入不能为空 if not new_name: return render(request,'add_publisher.html',{'err_msg':'输入不能为空','name':new_name}) # 设定不能与数据库现有数据重复 obj_list = models.Publisher.objects.filter(name=new_name) # 在数据库中查询数据是否存在 if obj_list: # 数据重复 return render(request, 'add_publisher.html', {'err_msg': '出版社名称已存在', 'name': new_name}) # orm往数据库中写入数据 if new_name and not obj_list: models.Publisher.objects.create(name=new_name) return redirect('/publisher_list/') # 如果不是post请求,还是返回本页面 return render(request,'add_publisher.html')
CBV : class base views 在试图里使用类处理请求
# url对应关系:url(r'^add_publisher/', views.add_publisher.as_view()), from django.views import View class add_publisher(View): def get(self,request): '''get请求''' return render(request, 'add_publisher.html') def post(self,request): # 获取提交的数据(括号内为input的name属性值),没有默认空字符串 new_name = request.POST.get('new_name', '').strip() # 设定输入不能为空 if not new_name: return render(request, 'add_publisher.html', {'err_msg': '输入不能为空', 'name': new_name}) # 设定不能与数据库现有数据重复 obj_list = models.Publisher.objects.filter(name=new_name) # 在数据库中查询数据是否存在 if obj_list: # 数据重复 return render(request, 'add_publisher.html', {'err_msg': '出版社名称已存在', 'name': new_name}) # orm往数据库中写入数据 if new_name and not obj_list: models.Publisher.objects.create(name=new_name) return redirect('/publisher_list/')
as_view()流程
1.程序启动的时候,执行as_view() 定义view函数并返回return self.dispatch(request, *args, **kwargs)
2.接收到请求的时候,执行view函数
1.实例化当前的类 将对象传给self
2.self.request = request
3.指定返回的self.dispatch方法:
1.判断请求方式是否允许
允许 ---- 通过反射拿到对应请求方式的方法 赋值给handler
不允许 ---- 执行self.http_method_not_allowed 赋值给handler
2.执行handler 得到HttpResponse对象 返回
给视图加装饰器
FBV本身就是函数,和普通的函数加装饰器的方法一样,没有区别
给CBV加装饰器
from django.utils.decorators import method_decorator #装饰器 def timer(func): def inner(*args,**kwargs): start = time.time() ret = func(*args,**kwargs) print('时间:{}'.format(time.time() - start)) return ret return inner # 1.加在方法上 @method_decorator(timer) def get(self,request): '''get请求''' return render(request, 'add_publisher.html') # 2.加在dispatch方法上 @method_decorator(timer) def dispatch(self, request, *args, **kwargs): # 将源码中的dispatch方法重新定义,相当于给所有方法加上装饰器 ret = super().dispatch(request, *args, **kwargs) return ret # 3.加在类上 @method_decorator(timer,name='post') @method_decorator(timer,name='get') # 在name中指定要加装饰器的方法 class AddPublisher(View): def dispatch(self, request, *args, **kwargs): pass def get(self,request): pass def post(self,request): pass @method_decorator(timer,name='dispatch') # 或者直接指定dispatch方法,效果同方法2一样,给所有方法加上装饰器 def dispatch(self, request, *args, **kwargs): pass def get(self,request): pass def post(self,request): pass
但是从参数角度来讲:
不使用method_decorator,打印args的结果:
(<app01.views.AddPublisher object at 0x03B465B0>, <WSGIRequest: GET '/add_publisher/'>)
使用method_decorator,打印args的结果:
(<WSGIRequest: GET '/add_publisher/'>,)
request
当一个页面被请求时,Django就会创建一个包含本次请求原信息的HttpRequest对象
Django会将这个对象自动传递给响应的视图函数,一般视图函数约定俗成地使用 request 参数承接这个对象
# 属性 request.method # 请求方法 request.GET # URL上携带的参数 request.POST # POST请求提交的数据 request.FILES # 上传的文件 request.path_info # 路径 不包含IP 端口 参数 request.body # 请求体 请求数据 字节 get没有请求体 request.META # 请求头的信息 全部大写 HTTP_开头 request.COOKIES request.session # 方法 request.get_full_path() # 路径 不包含IP和端口 包含参数 request.is_ajax() # 是否是ajax请求,布尔值 request.get_host() # 获取主机的IP和端口
上传文件
2.使用request.FILES方法获取文件
3.写入文件: 文件名.chunks 将文件分块 循环写入
from django.shortcuts import render def upload(request): if request.method == 'POST': file = request.FILES.get('file') # request.FILES获取到字典,通过键取值 with open(file.name,'wb') as f: # file.name拿到文件名 for chunk in file.chunks(): f.write(chunk) return render(request,'upload.html') # 文件会自动保存到与manage.py同一个路径下
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <form action="" method="post" enctype="multipart/form-data"> {% csrf_token %} 文件 <input type="file" name="s19"> <button>上传</button> </form> </body> </html>
response
render(request,'模板的文件名',{k1:v1}) 返回一个完整的HTML页面
redirect(要跳转的地址) 重定向 Location :地址
每个视图都需要实例化,填充和返回一个HttpResponse,render和redirect源码中都包含HttpResponse
JsonResponse是HttpResponse的子类,专门用来生成JSON编码的响应
默认只能传递字典类型,如果要传递非字典类型需要设置一下safe关键字参数
from django.http.response import JsonResponse def json_data(request): data = {'name':'alex','age':18} # lst = [1,2,3,4,5] return JsonResponse(data) # return JsonResponse(lst,safe=False) # 传输非字典类型