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格式的字符,需要通过JsonResponsejson_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方法,于是按对象的属性查找顺序,最后找到了父类Viewdispatch方法。换句话说,如果我们在MyLogin中定义了dispatch方法,此时就会覆盖View的,而使用我们自己定义的。
  • dispatch方法内,采用反射的方式,根据请求方式的不同,动态匹配到对象的get方法、post方法或者其他方法。

posted @ 2020-05-27 17:43  the3times  阅读(202)  评论(0编辑  收藏  举报