django——视图层
django——视图层
目录:
-
三板斧
-
JsonResponse
-
form表单上传文件
-
FBV与CBV
-
CBV源码
视图函数的返回值
视图函数必须返回一个HttpResponse对象
HttpResonse的本质就是一个类
-
解析为什么必须返回一个HttpResponse
在返回值后面的三板斧(render(返回一个网页地址)、HttpResponse(返回一个文本)、redirect(重定向))中,其调用的内置函数中,结果都会有一个返回值HttpResponse
1. render def render(): return HttpResponse(...) class HttpResponse(HttpResponseBase): pass 2.HttpResponse def 自定义(): return HttpResponse(...) 3.redirect def redirect(to, *args, permanent=False, **kwargs): redirect_class = HttpResponsePermanentRedirect if permanent else HttpResponseRedirect return redirect_class(resolve_url(to, *args, **kwargs))
三者之中都会调用HttpResponse这个类,故而是必须返回一个HttpResponse
返回json格式数据
-
JsonResponse()方法
使用JsonResponse()方法就相当于将该数据使用 json序列化,将该数据序列化为json格式的数据
user_dict = {'name': 'jason老师', 'pwd': 123, 'hobby': ['read', 'run', 'music']} json_str = json.dumps(user_dict, ensure_ascii=False) return HttpResponse(json_str) return JsonResponse(user_dict)
得出的结果大致一致,在有文本的时候,JsonResponse()类中需要添加一个参数'ensure_ascii':False 取消默认编码
-
修改取消默认编码的参数
1.首先进入JsonResponse方法的源码中 def __init__(self, data, encoder=DjangoJSONEncoder, safe=True, json_dumps_params=None, **kwargs): if json_dumps_params is None: json_dumps_params = {} data = json.dumps(data, cls=encoder, **json_dumps_params) super().__init__(content=data, **kwargs) # 这里的 json_dumps_params默认为{},需要再调用的时候在外部传参将默认编码的形式做出更改 JsonResponse(user_dict, json_dumps_params={'ensure_ascii':False})
注意:这里使用JsonResponse()方法只能转码字典形式,若想转码其他形式的数据时需要修改参数
-
当数据类型不为字典形式时修改的参数
JsonResponse主要是用于字典的序列化,若遇到其他类型需要序列化,需要将JsonResponse源码中的默认值safe=True,改为safe=False; JsonResponse(user_dict, json_dumps_params={'ensure_ascii':False}, safe=False )
form表单携带文件数据
-
form表单需要具备的条件
<form action="" method="POST" enctype="multipart/form-data"> </form>
1.method属性值必须是post
2.enctype属性值必须是multipart/form-data
满足两种属性值才可以对文件进行操作,否者只会得到其文件命
-
后端获取文件数据
res = request.FILES.get('前端设置的文件的接受名') # 保存文件数据 with open(res.name,'wb') as f: for line in res: f.write(line) # 将文件保存到后端
操作类似于request.POST
FBV与CBV
FBV与CBV的区别
类别 | 区别 |
---|---|
FBV | 基于函数的视图 |
CBV | 基于类的视图 |
FBV
FBV就是在视图层中,以函数来书写其业务逻辑
def index(request):
return HttpResponse()
在路由层设置接口
path('index/', views.index)
CBV
CBV就是在视图层中,以类来书写其业务逻辑
from django import views
class MyView(views.View): # 导过来的模块中有view这个类,需要继承这个类
def get(self, request):
return HttpResponse('我是CBV里面的get方法')
def post(self, request):
return HttpResponse('我是CBV里面的post方法')
路由层设置接口
path('func/', views.MyView.as_view())
"""这里的方法的名字是固定的, CBV会自动根据请求方式的不同匹配类中定义的方法并自动执行"""
CBV的源码
-
CBV 源码分析入口:
路由层中的路由匹配 path('func/', views.MyView.as_view())
-
类或对象在点属性的方法时,查找顺序是先找自身,若没有,在找这个方法的父类
-
进入as_view源码层寻找到其父类view,而view在设置的类中
-
绑定给类的as_view方法
@classonlymethod def as_view(cls, **initkwargs): # 绑定给类,类来调取的时候,将类当成第一个形参传入 def view(...): pass return view
只有一个返回值,而且返回的是view方法的结果view,
调用方法后,MyView.as_view()的结果为view
-
此时的路由匹配的结果为
path('func/', views.view)
故而CBV路由匹配本质:跟FBV是一致的
-
访问func触发view执行
def view(...): obj = cls() # 这里的cls是自己所定义的类,类加括号产生一个对象 return obj.dispatch() # 返回自己所写类中是否有dispatch方法,有则直接运行,没有则查找其父类
-
研究dispatch方法
http_method_names = ['get', 'post', 'put', 'patch', 'delete', 'head', 'options', 'trace'] def dispatch(...): # 先判断是否在常见的请求方法中 if request.method.lower() in self.http_method_names: func_name = getattr(obj,request.method.lower()) # 请求方法的函数名 = geattr(对象,'请求方法') func_name(...) # 最后执行操作