Django 学习视图之FBV与CBV
一. 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的更多相关文章
- django请求生命周期,FBV和CBV,ORM拾遗,Git
一.django 请求生命周期 流程图: 1. 当用户在浏览器中输入url时,浏览器会生成请求头和请求体发给服务端请求头和请求体中会包含浏览器的动作(action),这个动作通常为get或者post, ...
- python 全栈开发,Day84(django请求生命周期,FBV和CBV,ORM拾遗,Git)
一.django 请求生命周期 流程图: 1. 当用户在浏览器中输入url时,浏览器会生成请求头和请求体发给服务端请求头和请求体中会包含浏览器的动作(action),这个动作通常为get或者post, ...
- Django - 自定义分页、FBV和CBV
一.自定义分页(优势在于能够保存搜索条件) """ 分页组件使用示例: 1) 先取出所有数据USER_LIST 2) 实例化: obj = Pagination(requ ...
- Django【进阶】FBV 和 CBV
django中请求处理方式有2种:FBV 和 CBV 一.FBV FBV(function base views) 就是在视图里使用函数处理请求. 看代码: urls.py 1 2 3 4 5 6 7 ...
- Django视图之FBV与CBV
一. CBV与FBV CBV:Class Based View FBV:Function Based View 我们之前写过的都是基于函数的view,就叫FBV.还可以把view写成基于类的,那就是C ...
- Django生命周期,FBV,CBV
一. Django生命周期 首先我们知道HTTP请求及服务端响应中传输的所有数据都是字符串,在Django中,当我们访问一个的url时,会通过路由匹配进入相应的html网页中.Django的请求生命周 ...
- [Django学习]视图
视图 视图接受Web请求并且返回Web响应 视图就是一个python函数,被定义在views.py中 响应可以是一张网页的HTML内容,一个重定向,一个404错误等等 响应处理过程如下图: 1. UR ...
- django学习-视图练习
写一个真正有用的视图 每个视图必须要做的只有两件事: 返回一个包含被请求页面内容的HttpResponse对象,或抛出一个异常,比如Http404. 至于你还想干些什么,随便你. 你的视图可以从数据库 ...
- django中视图处理请求方式(FBV、CBV)
FBV FBV(function base views) 就是在视图里使用函数处理请求. 在之前django的学习中,我们一直使用的是这种方式,所以不再赘述. CBV CBV(class base v ...
随机推荐
- HDU1276-士兵队列训练问题 (Queue)
题很简单,STL中queue的基本使用. #include <bits/stdc++.h> using namespace std; int N,num; int main() { sca ...
- Java Interview Questions Summary
Spring 高并发 Java基础 多线程 正文. 多线程精选53题 1.什么是线程 线程是操作系统能够进行运算调度的最小单位,它被包含在进程之中,是进程中的实际运作单位.程序员可以通过它进行多处理器 ...
- java中路径的问题
在java中,涉及路径的问题有很多,不管在windows还是linux系统中,不要纠结”/“分隔符的使用,在windows系统中,资源加载器会自动的将”/“转换成”\“. 在java中获取资源的方式有 ...
- MYSQL命令练习及跳过数据库密码进行密码重新设置
2.看当前所有数据库:show databases; 3.进入mysql数据库:use mysql; 4.查看mysql数据库中所有的表:show tables; 5.查看user表中的数据: ...
- Python中令人迷惑的4个引用
第一个:执行时机的差异 1. array = [1, 8, 15] g = (x for x in array if array.count(x) > 0) array = [2, 8, 22] ...
- Python 中多进程、多线程、协程
进程: 一个运行的程序(代码)就是一个进程,没有运行的代码叫程序,进程是系统资源分配的最小单位,进程拥有自己独立的内存空间,所以进程间数据不共享.开销大. 线程: 调度执行的最小单位,也叫执行路径,不 ...
- springMVC的跳转
服务器内部跳转: return "forward:/forward/test1"; 或者 request.getRequestDispatcher(path).forward(r ...
- WLC RTU license
目前思科的某些WLC不是一定要license文件去安装,例如这里提到的RTU license. RTU:Right To Use Right to Use (RTU) licensing is a m ...
- Python下opencv使用笔记(十一)(详解hough变换检测直线与圆)
http://blog.csdn.net/on2way/article/details/47028969 http://blog.csdn.net/mokeding/article/details/1 ...
- Android Studio中 安卓模拟器 联网
方案一:之前做测试的时候发现虚拟机无法联网(浏览器打开 www.baidu.com, 显示 403 forbidden): 解决方案:关闭已经打开的虚拟机,进入到 SDK 安装目录下,按住 shift ...