内容概要
- 视图层必会三板斧
- 视图层之JsonResponse对象
- request对象获取文件
- 视图层之FBV与CBV
- CBV源码解析
视图层三板斧
render、redirec、HttpResponse
只要是用于处理请求的视图函数都必须返回HttpResponse对象
视图层之JsonResponse对象
使用JsonResponse对象需要先导入
django中的JsonResponse模块相当于对json序列化的数据类型的范围做了扩充,查看源码,其实还是使用的原始的json模块
from django.http import JsonResponse
# JsonResponse源码
class JsonResponse(HttpResponse):
def __init__(self, data, encoder=DjangoJSONEncoder, safe=True,
json_dumps_params=None, **kwargs):
if safe and not isinstance(data, dict):
raise TypeError(
'In order to allow non-dict objects to be serialized set the '
'safe parameter to False.'
)
if json_dumps_params is None:
json_dumps_params = {}
kwargs.setdefault('content_type', 'application/json')
data = json.dumps(data, cls=encoder, **json_dumps_params) # 还是使用json方法
super(JsonResponse, self).__init__(content=data, **kwargs)
代码验证
def ab_json(request):
1.HttpResponse传递字典 >>> 无法json序列化
user_dict = {"name":'jason','pwd':123,'hobby':'好好学习'}
dict_json = json.dumps(user_dict,ensure_ascii=False)
return HttpResponse(dict_json)
2.JsonResponse传递字典
user_dict = {'name': 'xiaoming', 'pwd': 123, 'hobby': '好好学习'}
return JsonResponse(user_dict,json_dumps_params={'ensure_ascii':False})
# 如果不想展示出来的中文乱码,需要设置json_dumps_params
3.JsonResponse传递列表
user_list = [11, 22, 33, 44, 55]
return JsonResponse(user_list, safe=False) # 防止报错,需要设置safe=False
视图层之request对象获取文件
form表单携带的文件类型的数据需要做到以下几点:
1.html页面请求方式 method 必须为Post
'''<form action="" method="post" enctype="multipart/form-data">'''
2.enctype必须为 multipart/form-data
'''<form action="" method="post" enctype="multipart/form-data">
<p>username:
<input type="text" name="username" class="form-control">
</p>
<p>files:
<input type="file" name="my_file" class="form-control" multiple(上传多个文件)>
</p>
<input type="submit" class="btn btn-success btn-block">
</form>'''
django后端则需要通过request.FILES来获取文件类型的数据
def ab_form(request):
if request.method == 'POST':
print(request.POST) # 不能获取文件数据,只能获取文件名字
print(request.FILES) # 专门获取文件数据
file_obj = request.FILES.get('my_file') # 'my_file'是input标签的name值
print(file_obj.name) # 查看文件名
with open(file_obj.name,'wb') as f:
for line in file_obj: # 相当于粘贴文件到当前文件夹
f.write(line)
request的其他方法
request.method
request.POST
request.GET
request.FILES
request.body # 存放的是接收过来的最原始的二进制数据
ps:request.POST、request.GET、request.FILES这些获取数据的方法其实都从body中获取数据并解析存放的;
request.path
获取路径即url
request.path_info
获取路径即url
request.get_full_path()
获取路径(url)并且还可以获取到路径(?...)后面携带的参数
视图层FBV与CBV
FBV
基于函数的视图
CBV
基于类的视图
# 视图层
from django import views
class MyLoginView(views.View):
def get(self, request):
return HttpResponse("from CBV get view")
def post(self, request):
return HttpResponse("from CBV post view")
# 路由层
path('login/', views.MyLoginView.as_view())
"""
如果请求方式是GET,则会自动执行类里面的get方法;
如果请求方式是POST,则会自动执行类里面的post方法;
"""
CBV源码剖析
1.路由层创建关系
path(r'login/', views.MyLoginView.as_view()) # MyLoginView是即将要创建的类名
分析:
as_view可以是普通的静态方法;
as_view可以是绑定给类的方法;
项目启动后,访问此路由,由于函数加括号调用优先级最高,会先执行as_view(),可以看成一个返回值;
2.在视图层中创建类
class MyLoginView(views.View):
def get(self, request):
return HttpResponse("from CBV get view")
def post(self, request):
return HttpResponse("from CBV post view")
# 使用get请求后,结果为:from CBV get view
# 使用post请求后,结果为:from CBV post view
分析:
类MyLoginView并没有相关方法能够识别get和post请求,那么必定在继承的父类中,我们接下来查看View源码
3.查看View源码
class View(object):
# 1、请求方式
http_method_names = ['get', 'post', 'put', 'patch', 'delete', 'head', 'options', 'trace'] # 共八种
# 2.as_view函数
@classonlymethod
def as_view(cls, **initkwargs):
... # 跳过部分代码
def view(request, *args, **kwargs):
... # 跳过部分代码
return self.dispatch(request, *args, **kwargs)
return view
def dispatch(self, request, *args, **kwargs):
if request.method.lower() in self.http_method_names:
handler = getattr(self, request.method.lower(), self.http_method_not_allowed)
else:
handler = self.http_method_not_allowed
return handler(request, *args, **kwargs)
分析:
运行步骤:
(1)url调用views.MyLoginView.as_view(),先执行as_view;
(2)as_view()的返回值为view,因此:
views.MyLoginView.as_view() == views.MyLoginView.view;
(3)路由匹配成功后执行view,执行类的dispatch方法(self.dispatch())
(4)执行dispatch,判断如果请求方式在八种方式中,获取该请求方式的对应字符(handler)后,并加括号运行该函数:return handler()
因此:
as_view() == view;
view() == dispatch() == handler();
总结:
views.MyLoginView.as_view() == handler(request, *args, **kwargs) # handler相当于不同的请求方式 >>> post,get...
标签:self,JsonResponse,request,视图,django,json,view
From: https://www.cnblogs.com/ddsuifeng/p/16981864.html