Django之视图层

目录

一、三板斧的使用

二、JsonReponse序列化类的使用

[三、 form表单上传文件](#三、 form表单上传文件)

数据准备

数据处理

(1)post请求数据

(2)文件数据获取

[四、 FBV与CBV](#四、 FBV与CBV)

五、CBV的源码分析

[as_view 方法](#as_view 方法)


一、三板斧的使用

  • HttpResponse
    • 返回字符串类型
  • render
    • 渲染html页面,并且在返回给浏览器之前还可以给html页面传值
  • redirect
    • 重定向页面

在视图文件中写视图函数的时候不能没有返回值了,默认返回的是None,页面上就会报错

python 复制代码
def render(request, template_name, context=None, content_type=None, status=None, using=None):
    content = loader.render_to_string(template_name, context, request, using=using)
    return HttpResponse(content, content_type, status)

二、JsonReponse序列化类的使用

json格式的数据:{"a":1}

json有什么用:跨语言传输

序列化:json.dumps

反序列化:json.loads

python 复制代码
from django.http import JsonResponse
def index(request):
    # user_dict = {'username':'kevin你好'}
    user_dict = [1, 2, 3, 4]
    # res = json.dumps(user_dict,ensure_ascii=False)
    # return  HttpResponse(res)
    # return JsonResponse(user_dict,json_dumps_params={'ensure_ascii':False})
    return JsonResponse(user_dict,safe=False)
    # return render(request,'index.html')

三、 form表单上传文件

python 复制代码
<form action="" method="post" enctype="multipart/form-data"></form>

form表单上传数据需要满足的条件:

  1. 请求方式必须是post
  2. enctype参数必须指定成 form-data 类型

数据准备

  • 路由
python 复制代码
# form 表单上传 下载文件
url('^ab_file/',views.ab_file),
  • 前端
python 复制代码
<form action="" method="post" enctype="multipart/form-data" class="form form-control">
    <p>username:<input type="text" name="username" class="form-control"></p>
    <p>file:<input type="file" name="file" class="form-control"></p>
    <input type="submit">
</form>

数据处理

(1)post请求数据
python 复制代码
def ab_file(request):
    if request.method == 'POST':
        # 只能获取到普通的文本数据,无法获取到文件数据
        print(request.POST)
    return render(request, 'file.html')
python 复制代码
<QueryDict: {'username': ['dream']}>
  • 通过这种方式,我们只能获取到我们输入的文本数据,而拿不到我们想要的文件数据
(2)文件数据获取
python 复制代码
def ab_file(request):
    if request.method == 'POST':
        # 获取文件数据
        print(request.FILES) # <MultiValueDict: {'file': [<InMemoryUploadedFile: img.png (image/png)>]}>
        # 提取文件数据 - 文件对象
        file_obj = request.FILES.get('file')
        # 提取文件名字 file_obj.name
        with open(file_obj.name, 'wb') as f:
            # 逐行读取文件数据
            # 官方推荐 加上 chunks 方法 等价于 一行行获取
            for line in file_obj.chunks():
                f.write(line)
    return render(request, 'file.html')
python 复制代码
<MultiValueDict: {'file': [<InMemoryUploadedFile: img.png (image/png)>]}>

四、 FBV与CBV

FBV:function based view -----》写的都是函数

CBV:class based view -----》写的都是类

CBV视图

python 复制代码
from django.views import View


class MyLogin(View):
    def get(self, request):
        print('get...')
        return HttpResponse("get")

    def post(self, request):
        return HttpResponse("hello postman!!!")
    
url(r'^login/', views.MyLogin.as_view()),

MBV和CBV各有各的特点,都有应用

  • CBV特点
    • 能够直接根据请求方式的不同直接匹配到对应的方法执行

五、CBV的源码分析

as_view 方法

路由对应函数内存地址:

python 复制代码
url(r'^login/', views.MyLogin.as_view()),

方法/函数名 加 括号 执行优先级最高

  • View类中得as_view方法的返回值是view函数名
  • 当请求来的时候,会触发view函数的执行
python 复制代码
def view(request, *args, **kwargs):
    # cls:Mylogin()------>self对象
    self = cls(**initkwargs)
    return self.dispatch(request, *args, **kwargs)  # View类里的dispatch

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)

from django.views import View


class MyLogin(View):
    http_method_names = ['get', 'post']
    def get(self, request):
        print('get...')
        self.index()
        return HttpResponse("get")

    def post(self, request):
        return HttpResponse("hello postman!!!")

    def index(self):
        pass

小结

python 复制代码
url(r'^login/', views.MyLogin.as_view()),
  • 当我们启动Django项目时
  • 会自动触发路由中的方法,调用 as_view 方法并自执行
  • 在执行后我们查看 as_view 方法的源码 发现
    • 在依次给我们的对象赋值后,最终返回了一个自执行的 dispatch 方法
  • 于是我们又去查看了 dispatch 方法
    • 在 dispatch 内部 ,先是将请求方式转换并进行校验
    • 然后开始校验需要调用的方法的调用位置,校验成功并拿到需要执行的方法执行
  • 在自己写的类中如果有相关的方法,会首先调用我们重写的类方法,并返回执行结果
    • 如果自己的类里面没有该方法 会去自己的父类中调用 父类的方法
      • 如果父类 以及 基类 都找不到则报错,抛出异常
相关推荐
码农派大星。3 分钟前
Spring Boot 配置文件
java·spring boot·后端
测试杂货铺6 分钟前
外包干了2年,快要废了。。
自动化测试·软件测试·python·功能测试·测试工具·面试·职场和发展
艾派森10 分钟前
大数据分析案例-基于随机森林算法的智能手机价格预测模型
人工智能·python·随机森林·机器学习·数据挖掘
小码的头发丝、36 分钟前
Django中ListView 和 DetailView类的区别
数据库·python·django
杜杜的man43 分钟前
【go从零单排】go中的结构体struct和method
开发语言·后端·golang
幼儿园老大*44 分钟前
走进 Go 语言基础语法
开发语言·后端·学习·golang·go
llllinuuu1 小时前
Go语言结构体、方法与接口
开发语言·后端·golang
cookies_s_s1 小时前
Golang--协程和管道
开发语言·后端·golang
为什么这亚子1 小时前
九、Go语言快速入门之map
运维·开发语言·后端·算法·云原生·golang·云计算
想进大厂的小王1 小时前
项目架构介绍以及Spring cloud、redis、mq 等组件的基本认识
redis·分布式·后端·spring cloud·微服务·架构