Django---CBV和FBV的使用,CBV的流程,给视图加装饰器,Request对象方法,属性和Response对象,form表单的上传...

mac2022-06-30  62

Django---CBV和FBV的使用,CBV的流程,给视图加装饰器,Request请求对象方法,属性和Response响应对象,form表单的上传

一丶CBV和FBV

      在Django中存在存在两种url和视图对应的形式:类和函数

CBV:类视图

##### class based view 基于类 ### 出版社添加 urls.py中填写url和类的对应关系. #PublishAdd是类,要执行as_view()方法 url('^publish_add',views.PublishAdd.as_view()), # CBV ### 添加出版社,在app下的views.py写代码 class PublishAdd(View): def get(self, request): # 执行get请求 , request手动传参 return render(request, 'publish_add.html') def post(self, request): # 执行post请求 pname = request.POST.get('pname') paddr = request.POST.get('paddr') if not pname: error = '内容不允许为空' elif models.Publish.objects.filter(pname=pname): error = '出版社已存在' else: # 往数据库中插入数据 models.Publish.objects.create(pname=pname, paddr=paddr) return redirect(to='/publish_list/') res = {'error': error, 'pname': pname, 'paddr': paddr} return render(request, 'publish_add.html', res)

FBV:函数视图

## function based view 基于函数 #出版社添加 url('^publish_add',views.publish_add), # FBV ### publish_add 函数 def publish_add(request): error, pname, paddr = '', '', '' if request.method == 'POST': # 判断请求的方式是不是post pname = request.POST.get('pname') paddr = request.POST.get('paddr') if not pname: error = '内容不允许为空' elif models.Publish.objects.filter(pname=pname): error = '出版社已存在' else: # 往数据库中查数据 models.Publish.objects.create(pname=pname, paddr=paddr) return redirect(to='/publish_list/') res = {'error': error, 'pname': pname, 'paddr': paddr} return render(request, 'publish_add.html', res)

二丶CBV的运行流程

1. 项目启动时,运行urls.py。 url(r'^publisher_add/',views.AddPublisher.as_view() ), AddPublisher.as_view() 执行 ——》 执行当前类的as_view方法,如果没有当前类没有,就执行父类的View函数. 2. 请求到来时,实行view函数: 1. 实例化AddPublisher ——》 self 2. self.request = request 3. 执行View中self.dispatch(request, *args, **kwargs) 1. 判断请求方式是否被允许 1. 允许 通过反射获取请求方式对应的方法 ——》 handler 2. 不允许 self.http_method_not_allowed ——》 handler 2. 执行handler 获取到响应 ### 源码: ### view 函数 def view(request, *args, **kwargs): # 执行view函数 self = cls(**initkwargs) # 实例化一个当前类对象,cls指的是当前类名.加()实例化对象 if hasattr(self, 'get') and not hasattr(self, 'head'): self.head = self.get # 给对象封装属性 self.request = request self.args = args self.kwargs = kwargs return self.dispatch(request, *args, **kwargs) #### 重点:执行调遣函数,确认是执行哪一个方法. view.view_class = cls view.view_initkwargs = initkwargs # take name and docstring from class update_wrapper(view, cls, updated=()) # and possible attributes set by decorators # like csrf_exempt from dispatch update_wrapper(view, cls.dispatch, assigned=()) return view # 返回一个view函数执行的结果 ### despatch函数 def dispatch(self, request, *args, **kwargs): # 判断请求是否被允许 if request.method.lower() in self.http_method_names: # 通过反射去执行具体的请求方法对应的请求函数. handler = getattr(self, request.method.lo handler = self.http_method_not_allowed return handler(request, *args, **kwargs) # 把结果交给handler处理 ,handler是执行的是http_method_not_allowed方法

三丶给视图加装饰器

CBV加装饰器

PS:# 在get方法上也可以直接加上装饰器.也能实现额外的功能,但是不推荐使用.最好是使用method_decorator()进行'加工'装饰 from django.utils.decorators import method_decorator # 给方法加上装饰器 ### 计时间装饰器 def timmer(func): def inner(*args, **kwargs): # print('查看是方法还是函数:',func) # print('查看参数的类型:',args,type(args)) # print(kwargs) start_time = time.time() ret = func(*args, **kwargs) print(f'当前函数运行时间:{time.time() - start_time}') return ret return inner @method_decorator(timmer, name='dispatch') # 在类上指定具体的某个方法加上装饰器 class PublishAdd(View): # @timmer # 这种方式也可以实现功能,但是传递的参数不一样,不推荐使用. 参数回到计时装饰器查看 # 函数 : 这是一个函数 <function PublishAdd.dispatch at 0x000001F6B675CEA0> # 参数 : 不能直接获取WSGIRequest对象 (<app01.views.PublishAdd object at 0x000001F6B6898B38>, <WSGIRequest: GET '/publish_add/'>) # @method_decorator(timmer) # 给所有的请求方法都加上了装饰器 # 绑定方法: <function method_decorator.<locals>._dec.<locals>._wrapper.<locals>.bound_func at 0x0000019DB9AE2D08> # 参数: (<WSGIRequest: GET '/publish_add/'>,) <class 'tuple'> def dispatch(self, request, *args, **kwargs): ret = super(PublishAdd, self).dispatch(request, *args, **kwargs) return ret def get(self, request): return render(request, 'publish_add.html') def post(self, request): pname = request.POST.get('pname') paddr = request.POST.get('paddr') if not pname: error = '内容不允许为空' elif models.Publish.objects.filter(pname=pname): error = '出版社已存在' else: # 往数据库中插入数据 models.Publish.objects.create(pname=pname, paddr=paddr) return redirect(to='/publish_list/') res = {'error': error, 'pname': pname, 'paddr': paddr} return render(request, 'publish_add.html', res)

FBV加装饰器

# 由于是函数可以直接加上装饰器 ### 计时间装饰器 def timmer(func): def inner(*args, **kwargs): # print('查看是方法还是函数:',func) # print('查看参数的类型:',args,type(args)) # print(kwargs) start_time = time.time() ret = func(*args, **kwargs) print(f'当前函数运行时间:{time.time() - start_time}') return ret return inner @timmer def publish_add(request): error, pname, paddr = '', '', '' if request.method == 'POST': # 判断请求的方式是不是post pname = request.POST.get('pname') paddr = request.POST.get('paddr') if not pname: error = '内容不允许为空' elif models.Publish.objects.filter(pname=pname): error = '出版社已存在' else: # 往数据库中查数据 models.Publish.objects.create(pname=pname, paddr=paddr) return redirect(to='/publish_list/') res = {'error': error, 'pname': pname, 'paddr': paddr} return render(request, 'publish_add.html', res)

四丶Request请求 -- 属性和方法

ret2 = request.method # 获得请求方式 ret3 = request.GET # GET请求方式,url上携带的参数 ret4 = request.POST # POST请求方式,post请求提交的参数 ret5 = request.path_info #路径信息 (不包含IP和端口 也不包含查询参数) ret6 = request.body # 请求体的信息 ret7 = request.COOKIES # cookie信息 ret8 = request.session # session信息 ret9 = request.FILES # 获得上传文件信息 ret10 = request.META # 获得所有的头信息 ret11 = request.is_ajax() ret12 = request.get_full_path()

五丶form表单上传文件

###input框的类型为file ,需要在 form表单设置method提交方式 'post' 和 enctype='multipart/form-data' <form class="form-inline" action="" method="post" enctype="multipart/form-data"> <div class="form-group"> <label for="exampleInputName2">文件上传</label> <input type="file" class="form-control" id="" name="file-upload" multiple> </div> <button type="submit" class="btn btn-default">上传</button> </form> ## 上传文件的后端代码 def post(self,request): file_data=request.FILES.get('file-upload') # 使用FILES获得上传文件 print(file_data,type(file_data)) # 打印类型 upload_file_dirs=os.path.dirname(os.path.dirname(os.path.abspath(__file__))) print(upload_file_dirs) with open(os.path.join(upload_file_dirs,'upload',file_data.name),'wb') as f: for line in file_data.chunks(): f.write(line) return redirect(to='/index_test/')

六丶Response响应

# HttpResponse 返回字符串 # render 返回一个页面 ,基于HttpResponse # redirect 重定向 ,基于HttpResponse # JsonResponse 返回json格式的数据 ,基于HttpResponse ### 最终都返回的是HttpResponse的字符串

      JsonResponse的使用

from django.http.response import JsonResponse # 导入模块 def json_response(request): data={'name':'abc','age':18} # 字典类型的数据,默认支持 data2=['1','2','3'] # 默认不支持列表或其他类型的数据.需要设置一个条件,safe=False # 如:JsonResponse(data2,safe=False) return JsonResponse(data)

转载于:https://www.cnblogs.com/dengl/p/11439401.html

相关资源:Django 视图 – FBV 与 CBV
最新回复(0)