Django之视图函数层 (必会三板斧 JsonResponse对象 request对象获取文件 FBV与CBV CBV源码剖析)
目录
视图层之必会三板斧
用来处理请求的视图函数都必须返回HttpResponse对象
- 情况一:啥也不返回

这里会报一个没有返回HttpResponse对象的错误,由此可见必须要返回一个HttpResponse对象

- 情况二:返回HttpResponse对象
点击Ctrl键查看源码可见是HttpResponse类,所以会返回一个值

- 情况三:返回render对象
点击Ctrl键查看源码可见是render返回的是HttpResponse对象

- 情况四:返回redirct对象
点击Ctrl键查看源码可见是redirect最终有个祖先类返回的是HttpResponse对象

视图层之JsonResponse对象
- 如果返回浏览器的是中文,则要看源码,去给json_dumps_params={'ensure_ascii': False}加参数

from django.http import JsonResponse
user_dict = {'username': 'tank哈哈哈', 'age': 20}
json_str = JsonResponse(user_dict, json_dumps_params={'ensure_ascii': False})
- 如果返回浏览器的是列表,根据看报错信息,则要看源码,去给safe=False改参数

l = [1,2,3,4]
json_str = JsonResponse(l,safe=False)
视图层之request对象获取文件
- 表单上传问价需要满足的条件是:
- 请求方式method必须是:post
- enctype必须是multipart/form-data
django后端需要通过request.FILES获取文件类型的数据
<form action="" method="post" enctype="multipart/form-data">
def ab_file(request):
# 接收用户提交过来的数据
# request.POST 只能接收普通参数,不能接收文件数据
print(request.POST) # <QueryDict: {'username': ['SDASD']}>
# 如何接收文件数据
print(request.FILES) # <MultiValueDict: {'myfile': [<InMemoryUploadedFile: 123.png (image/png)>]}>
file_obj = request.FILES.get('myfile')
with open(file_obj.name, 'wb') as f:
# f.write(file_obj)
for line in file_obj:
f.write(line)
return render(request, 'ab_file.html')
视图层之FBV与CBV
- FBV
-
基于函数的视图
def index(request):
return HttpResponse对象
- CBV
-
基于类的视图
from django import views
class MyLoginView(views.View):
def get(self, request):
return HttpResponse('from CBV get function')
def post(self, request):
return HttpResponse('from CBV post function')
path('login/', views.MyLoginView.as_view())
# 会自动根据请求方法的不同自动匹配对应的方法并执行
CBV源码剖析(重点)
执行流程版本(一):
-
路由配置:path(r'test/', views.Test.as_view()),
-
请求通过中间件后进入路由--->根据路由匹配,一旦成功,会执行后面函数(request)--->
-
本质就是执行了as_view内部的view函数---->内部又调用了self.dispatch---->
-
根据请求方式,执行不同的方法(必然get请求,就会执行咱么写的视图类的get方法)
执行流程版本(二):
1.从CBV的路由匹配切入 path('login/', views.MyLoginView.as_view())
①.类名点名字(名字的查找问题)
②.类名点名字并加括号调用(静态方法、绑定给类的方法)*
2.函数名加括号执行优先级最高 项目一启动就会自动执行as_view方法path('login/', views.view) CBV路由本质还是FBV
3.浏览器地址栏访问login路由需要执行view函数
①.产生我们自己编写类的对象
②.对象调用dispatch方法(注意查找顺序)
4.研究父类中的dispatch方法
获取当前请求方法并转小写 之后利用反射获取类中对应的方法并执行
分析
先创建一个视图类

配置路由

然后按住ctrl键点进去看as_view的源码

这里的self是view这个类的对象,我们在类视图继承了view这个类,就是我们Test这个类的对象, views.Test.as_view()-------------------->View类里面的as_view方法中得view方法的内存地址

这里返回了一个dispatch方法,但是我们并没有定义这个方法,所以就去Test的父类View里面去找

然后再来分析

找到dispatch

如果在这里面通过反射getattr去这self这个对象里也就是Test这个类的对象通过传过来的名字比如get去取东西,所以类里面的get必须带request


浙公网安备 33010602011771号