一. CBV与FBV

CBV:Class Based View

FBV:Function Based View

我们之前写过的都是基于函数的view,就叫FBV。还可以把view写成基于类的,那就是CBV。

下面我们就拿添加用户为例:

1.FBV版本

首先:urls.py 的与视图关系编写为:path('register/', views.register),

然后是视图函数的内容:

from django.contrib.auth.models import User

from django.shortcuts import render, HttpResponse, redirect

# 注册及验证 (前端模板是以ajax实现)

def register(request):

if request.method == "GET":

return render(request, "register.html")

if request.method == "POST":

username = request.POST.get("username")

password = request.POST.get("pwd")

print(username)

print(password)

User.objects.create_user(username=username, password=password)  # User是以个对象

return redirect("/index/")

2.CBV版本

首先:urls.py 的与视图关系编写为:path('register/', views.Register.as_view()),

然后是视图函数类编写的内容:

from django.views import View

class Register(View):

def get(self, request):

return render(request, "register.html")

def post(self, request):

username = request.POST.get("username")

password = request.POST.get("pwd")

print(username)

print(password)

User.objects.create_user(username=username, password=password)

# User是以个对象

return redirect("/index/")

二. 给视图加装饰器

1. 使用装饰器装饰FBV

FBV本身就是一个函数,所以和给普通的函数加装饰器无差:

# 一个时间的装饰器来验证是否运行了装饰器

def wrapper(func):

def inner(*args, **kwargs):

start_time = time.time()

time.sleep(2)

ret = func(*args, **kwargs)

end_time = time.time()

print("used:", end_time - start_time)

return ret

return inner

@wrapper

def register(request):

if request.method == "GET":

return render(request, "register.html")

if request.method == "POST":

username = request.POST.get("username")

password = request.POST.get("pwd")

print(username)

print(password)

User.objects.create_user(username=username, password=password)  # User是以个对象

return redirect("/index/")

访问的时候大概停留两秒再进行访问。并在后台打印出运行后的时间。

2.使用装饰器装饰CBV

类中的方法与独立函数不完全相同,因此不能直接将函数装饰器应用于类中的方法 ,我们需要先将其转换为方法装饰器。Django中提供了method_decorator装饰器用于将函数装饰器转换为方法装饰器。

使用之前需要先导入相应的包

from django.views import View

from django.utils.decorators import method_decorator

方式一:给某个方法加上装饰器(此例给get方法加上)

class Register(View):

@method_decorator(wrapper)

def get(self, request):

return render(request, "register.html")

def post(self, request):

username = request.POST.get("username")

password = request.POST.get("pwd")

print(username)

print(password)

User.objects.create_user(username=username, password=password)

# User是以个对象

return redirect("/index/")

方式二:加在dispatch方法上面,会给类下的所有方法加上此装饰器

class Register(View):

# 加在dispatch方法上面,会给类下的所有方法加上此装饰器

@method_decorator(wrapper)

def dispatch(self, request, *args, **kwargs):

#这样的写法兼容python2*

obj = super(Register, self).dispatch(request, *args, **kwargs)

# python3写法如下(此方法不兼容python2*)

# obj = super().dispatch(request, *args, **kwargs)

return obj

def get(self, request):

return render(request, "register.html")

def post(self, request):

username = request.POST.get("username")

password = request.POST.get("pwd")

print(username)

print(password)

User.objects.create_user(username=username, password=password)

# User是以个对象

return redirect("/index/")

此方式会给类下的所有方法加上此装饰器,也就是在这个注册过程运行了两次的装饰器,一次GET方法访问网页,一次POST方法注册。

方式三:加在类上面

@method_decorator(wrapper, name="post")

@method_decorator(wrapper, name="get")  # 给哪个方法加,就要指定name

class Register(View):

def get(self, request):

return render(request, "register.html")

def post(self, request):

username = request.POST.get("username")

password = request.POST.get("pwd")

print(username)

print(password)

User.objects.create_user(username=username, password=password)  # User是以个对象

return redirect("/index/")

上面加装饰器的方法是有固定格式的:

@method_decorator(装饰器名, name="类中需要装饰器的函数")

可以从源码中看出格式固定如截图:

补充:

以上的例子均可以使用下面的前端模板register.html

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<!-- 新 Bootstrap 核心 CSS 文件 -->
<link href="https://cdn.staticfile.org/twitter-bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet">
<!-- jQuery文件。务必在bootstrap.min.js 之前引入 -->
<script src="https://cdn.staticfile.org/jquery/2.1.1/jquery.min.js"></script>
<!-- 最新的 Bootstrap 核心 JavaScript 文件 -->
<script src="https://cdn.staticfile.org/twitter-bootstrap/3.3.7/js/bootstrap.min.js"></script>
</head>
<body> <div class="container">
<div class="row con"> <form action="" method="post">
{% csrf_token %}
<div class="form-group col-sm-4 col-sm-offset-4">
<h2>注册用户</h2>
<label for="exampleInputEmail1">用户名</label>
<input type="text" class="form-control" id="exampleInputEmail1" placeholder="用户名" name="username">
</div>
<div class="form-group col-sm-4 col-sm-offset-4">
<label for="exampleInputPassword1">密码</label>
<input type="password" class="form-control" id="exampleInputPassword1" placeholder="密码" name="pwd">
</div>
<div class="form-group col-sm-6 col-sm-offset-3">
<button type="submit" class="btn btn-default col-sm-offset-2">确认</button>
<button type="submit" class="btn btn-default col-sm-offset-2">返回</button> </div> </form> </div>
</div>
</body>
</html>

register.html

Django 学习视图之FBV与CBV的更多相关文章

  1. django请求生命周期,FBV和CBV,ORM拾遗,Git

    一.django 请求生命周期 流程图: 1. 当用户在浏览器中输入url时,浏览器会生成请求头和请求体发给服务端请求头和请求体中会包含浏览器的动作(action),这个动作通常为get或者post, ...

  2. python 全栈开发,Day84(django请求生命周期,FBV和CBV,ORM拾遗,Git)

    一.django 请求生命周期 流程图: 1. 当用户在浏览器中输入url时,浏览器会生成请求头和请求体发给服务端请求头和请求体中会包含浏览器的动作(action),这个动作通常为get或者post, ...

  3. Django - 自定义分页、FBV和CBV

    一.自定义分页(优势在于能够保存搜索条件) """ 分页组件使用示例: 1) 先取出所有数据USER_LIST 2) 实例化: obj = Pagination(requ ...

  4. Django【进阶】FBV 和 CBV

    django中请求处理方式有2种:FBV 和 CBV 一.FBV FBV(function base views) 就是在视图里使用函数处理请求. 看代码: urls.py 1 2 3 4 5 6 7 ...

  5. Django视图之FBV与CBV

    一. CBV与FBV CBV:Class Based View FBV:Function Based View 我们之前写过的都是基于函数的view,就叫FBV.还可以把view写成基于类的,那就是C ...

  6. Django生命周期,FBV,CBV

    一. Django生命周期 首先我们知道HTTP请求及服务端响应中传输的所有数据都是字符串,在Django中,当我们访问一个的url时,会通过路由匹配进入相应的html网页中.Django的请求生命周 ...

  7. [Django学习]视图

    视图 视图接受Web请求并且返回Web响应 视图就是一个python函数,被定义在views.py中 响应可以是一张网页的HTML内容,一个重定向,一个404错误等等 响应处理过程如下图: 1. UR ...

  8. django学习-视图练习

    写一个真正有用的视图 每个视图必须要做的只有两件事: 返回一个包含被请求页面内容的HttpResponse对象,或抛出一个异常,比如Http404. 至于你还想干些什么,随便你. 你的视图可以从数据库 ...

  9. django中视图处理请求方式(FBV、CBV)

    FBV FBV(function base views) 就是在视图里使用函数处理请求. 在之前django的学习中,我们一直使用的是这种方式,所以不再赘述. CBV CBV(class base v ...

随机推荐

  1. opencv python:图像梯度

    一阶导数与Soble算子 二阶导数与拉普拉斯算子 图像边缘: Soble算子: 二阶导数: 拉普拉斯算子: import cv2 as cv import numpy as np # 图像梯度(由x, ...

  2. 一年读100本书---HHR,NZJ---19年最后4个月

    那些自律到极致的人,都拥有了开挂的人生.生物钟,绝对一致之后,一切都会很高效. 19年最后一个季度的HHR计划:还剩下3个月的时间,主要搞定几件事情:创业(以太一堂,混沌大学),工作能力(推荐算法工程 ...

  3. RT_THREAD之nano学习

    nona版本为精简版本,只保留FISH(选配)最小内核,可以适配STM的STD.HAL/LL库,需要手动进行移植:现在可以在KEIL MDK/CUBEMX中进行集成,也可以RT-Thread Nano ...

  4. GCD: 求两数最大公因数算法【欧几里得法】原理的个人理解 (80%图片讲解!)

    那么,求 a,b 的最大公因数就是求最大的,能均分a,b的块!  

  5. ASP.NET Core搭建多层网站架构【8.3-编写角色业务的增删改】

    2020/01/29, ASP.NET Core 3.1, VS2019 摘要:基于ASP.NET Core 3.1 WebApi搭建后端多层网站架构[8.3-编写角色业务的增删改] 编写最简单的增删 ...

  6. (Java多线程系列九)线程池

    线程池 1.什么是线程池 线程池是指在初始化一个多线程应用程序过程中创建一个线程集合,然后在需要执行新的任务时重用这些线程而不是新建一个线程.线程池中线程的数量通常取决于可用内存数量和应用程序的需求. ...

  7. ln N! -> N(lnN -1)

  8. 用for循环写这段代码

    之前用while循环写了一段代码,现在改为用for循环来写,代码如下: hongtao_age = 38 for i in range(5): guess_age = int(input(" ...

  9. Centos5.5更新源

    将之前的CentOS-Base.repo文件里的内容换成如下内容 vi /etc/yum.repos.d/CentOS-Base.repo # CentOS-Base.repo## The mirro ...

  10. 给Linux系统运维新手的四点建议

    随着计算机的普及.互联网的发展,原本黑客手中的攻城利器---Linux,渐渐进入到普通群众的视线里,让越来越多的人接触到Linux,并学习Linux进而投身到Linux运维工作中去. 学习Linux的 ...