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>