django视图层
django视图层功能:处理对应url的请求,并返回响应数据;这个请求-响应过程中可能涉及到2点:(1)视图层和模型层打交道,访问数据库数据;(2)视图层将某些数据传递给模版层的html模版文件,渲染后显示在前端页面。
三件套
# HttpResponse, 返回字符串类型
return HttpResponse('Hello World')
# render, 将模板文件渲染成一个html文件然后返回给浏览器,还支持给模板文件传数据(字段的格式)
return render(request, 'index.html', locals())
# redirect, 重定向,支持固定的url\反向解析
return redirect('/index/') # url
return redirect('name_of_index') # 别名,支持反向解析成 '/index/',不过仅支持不带分组的;带分组的还是需要使用reverse()
结论:三者内部返回的都是HttpResponse对象
render简单内部原理
from django.template import Template, Context
def book_list(request):
book_queryset = models.BookTest.objects.filter().first().author
res = Template('<h1>{{book_queryset}}</h1>')
context = Context({'book_queryset': book_queryset})
ret = res.render(context)
return HttpResponse(ret)
# return render(request, 'book_list.html', locals())
JsonResponse对象
前后端数据交互需要使用到json作为过渡,实现跨语言传输数据。
import json
from django.http import JsonResponse
def ab_json(request):
user_dict = {'hello':'你好the3times','info':'ok'}
l = [111,222,333,444,555]
# 读源码掌握用法
return JsonResponse(user_dict, json_dumps_params={'ensure_ascii':False})
return JsonResponse(l, safe=False)
# 默认只能序列化字典 序列化其他需要加safe参数
JsonResponse
内部序列化是基于json模块的dumps()
,在序列化中文时,会将字符串转码为unicode格式的字符,需要通过JsonResponse
的json_dumps_params
参数,将json需要的参数ensure_ascii
转交给dumps()
补充:前端js的序列化&反序列化方法:JSON.stringify()、JSON.parse()
form表单上传文件
form表单上传文件类型的数据
- 1.method必须指定成post
- 2.enctype必须换成formdata
后端视图函数接收post请求提交的文件数据需要使用request.FILES
,普通数据使用request.POST
def ab_file(request):
if request.method == 'POST':
print(request.FILES) # 获取文件数据
# <MultiValueDict: {'file': [<InMemoryUploadedFile: u=1288812541,1979816195&fm=26&gp=0.jpg (image/jpeg)>]}>
file_obj = request.FILES.get('file') # 文件对象
print(file_obj.name) # 文件对象的名字
with open(file_obj.name, 'wb') as f:
for line in file_obj.chunks():
f.write(line)
return render(request,'form.html')
# 保存文件时,推荐加上chunks方法,其实跟不加是一样的都是一行行的读取
request对象方法
request.method
request.POST
request.GET
request.FILES # 获取上传文件数据
request.body # 原生的浏览器发过来的二进制数据 后面详细的讲
request.path
request.path_info # 等同于 request.path, 不包含url中?后面的部分
request.get_full_path() # 获取完整的url及问号后面的参数
FBV与CBV
基于函数的视图&基于类的视图。
# urls.py
url(r'^login/', views.MyLogin.as_view())
# views.py
from django.views import View
class MyLogin(View):
def get(self,request):
return render(request, 'form.html')
def post(self,request):
return HttpResponse('post方法')
CBV特点:能够直接根据请求方式的不同直接匹配到对应的方法执行。
CBV源码
核心知识点:闭包 + 反射
- 突破口:
url(r'^login/', views.MyLogin.as_view())
,as_view
是类方法,此处类直接调用返回一个闭包函数view
。于是整个url比配关系变成了:url(r'^login/', views.view)
,这种变形后的形式就和FBV的形式一致了。 - 闭包函数
view
内事例化MyLogin
对象,即实例化一个处理匹配该url
的一个对象;初始化该对象,并调用对象的dispatch
方法。 - 该对象自己没有
dispatch
方法,于是按对象的属性查找顺序,最后找到了父类View
的dispatch
方法。换句话说,如果我们在MyLogin
中定义了dispatch
方法,此时就会覆盖View
的,而使用我们自己定义的。 dispatch
方法内,采用反射的方式,根据请求方式的不同,动态匹配到对象的get
方法、post
方法或者其他方法。