一 CBV与FBV

  • CBV:Class Based View
  • FBV:Function Based View
  • 之前写过的都是基于函数的view,就叫FBV。还可以把view写成基于类的,那就是CBV。

1.1 创建项目

root@darren-virtual-machine:~/PycharmProjects# django-admin startproject cbv_test

root@darren-virtual-machine:~/PycharmProjects# cd cbv_test/

root@darren-virtual-machine:~/PycharmProjects/cbv_test# python3 manage.py startapp app01

setting注册app

INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'app01.apps.App01Config',
]

root@darren-virtual-machine:~/PycharmProjects/cbv_test# mkdir templates

root@darren-virtual-machine:~/PycharmProjects/cbv_test# vim cbv_test/settings.py

TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [os.path.join(BASE_DIR,"templates")],
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
],
},
},
]

路由分发

from django.contrib import admin
from django.urls import path,include urlpatterns = [
path('admin/', admin.site.urls),
path('app01/',include(app01.urls)),
]

配置一个登录页面

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h3>用户登录</h3>
<form action="" method="POST">
{% csrf_token %}
<p>用户名:<input type="text" name="username"></p>
<p>密 码:<input type="password" name="password"></p>
<input type="submit">
</form> </body>
</html>

url文件

from django.urls import  path,re_path
from app01 import views urlpatterns = [
path('login/',views.login),
]

views视图文件

from django.shortcuts import render,redirect,HttpResponse

# Create your views here.
def login(request):
if request.method == "GET":
return render(request,"login.html")
else:
username = request.POST.get("username")
password = request.POST.get("password")
if username == "joy" and password == "123456":
return HttpResponse("login success...")
else:
return render(request,"login.html")

访问

1.2 使用CBV改写

urls文件

from django.urls import  path,re_path
from app01 import views urlpatterns = [
path('login_fbv/',views.login),
path('login_cbv/', views.Login.as_view()),
]

views文件

from django.shortcuts import render,redirect,HttpResponse
from django.views import View # Create your views here.
def login(request):
if request.method == "GET":
return render(request,"login.html")
else:
username = request.POST.get("username")
password = request.POST.get("password")
if username == "joy" and password == "123456":
return HttpResponse("login success...")
else:
return render(request,"login.html") #CBV
class Login(View):
def get(self,request):
return render(request, "login.html")
def post(self,request):
username = request.POST.get("username")
password = request.POST.get("password")
if username == "joy" and password == "123456":
return HttpResponse("login success...")
else:
return render(request, "login.html")

访问http://127.0.0.1:8000/app01/login_cbv/登录

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

1.3 使用装饰器装饰CBV

给CBV加装饰器

from django.shortcuts import render,redirect,HttpResponse
from django.views import View
import time # Create your views here. def timer(func):
def inner(request,*args,**kwargs):
start_time = time.time()
time.sleep(2)
rep = func(request,*args,**kwargs)
end_time = time.time()
print (end_time-start_time)
return rep
return inner #FBV
@timer
def login(request):
if request.method == "GET":
return render(request,"login.html")
else:
username = request.POST.get("username")
password = request.POST.get("password")
if username == "joy" and password == "123456":
return HttpResponse("login success...")
else:
return render(request,"login.html")

1.4 使用装饰器装饰FBV

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

1.4.1 给某个方法加上装饰器

此例给get方法加上)

from django.shortcuts import render,redirect,HttpResponse
from django.views import View
import time
from django.utils.decorators import method_decorator
# Create your views here. def timer(func):
def inner(request,*args,**kwargs):
start_time = time.time()
time.sleep(2)
rep = func(request,*args,**kwargs)
end_time = time.time()
print (end_time-start_time)
return rep
return inner #FBV
@timer
def login(request):
if request.method == "GET":
return render(request,"login.html")
else:
username = request.POST.get("username")
password = request.POST.get("password")
if username == "joy" and password == "123456":
return HttpResponse("login success...")
else:
return render(request,"login.html") #CBV
class Login(View):
@method_decorator(timer)
def get(self,request):
return render(request, "login.html")
def post(self,request):
username = request.POST.get("username")
password = request.POST.get("password")
if username == "joy" and password == "123456":
return HttpResponse("login success...")
else:
return render(request, "login.html")

访问http://127.0.0.1:8000/app01/login_cbv/,只有get有,post并没有用到装饰器

[10/Apr/2020 11:27:53] "GET /app01/login_cbv HTTP/1.1" 301 0
2.024909496307373
[10/Apr/2020 11:27:55] "GET /app01/login_cbv/ HTTP/1.1" 200 456
[10/Apr/2020 11:28:05] "POST /app01/login_cbv/ HTTP/1.1" 200 16

1.4.2 加在dispatch方法上面

会给类下的所有方法加上此装饰器

from django.shortcuts import render,redirect,HttpResponse
from django.views import View
import time
from django.utils.decorators import method_decorator
# Create your views here. def timer(func):
def inner(request,*args,**kwargs):
start_time = time.time()
time.sleep(2)
rep = func(request,*args,**kwargs)
end_time = time.time()
print (end_time-start_time)
return rep
return inner #FBV
@timer
def login(request):
if request.method == "GET":
return render(request,"login.html")
else:
username = request.POST.get("username")
password = request.POST.get("password")
if username == "joy" and password == "123456":
return HttpResponse("login success...")
else:
return render(request,"login.html") #CBV
class Login(View):
@method_decorator(timer)
def dispatch(self, request, *args, **kwargs):
obj = super().dispatch(request,*args,**kwargs)
return obj #这里必须返回,否则Httpresponse错误
#@method_decorator(timer)
def get(self,request):
return render(request, "login.html")
def post(self,request):
username = request.POST.get("username")
password = request.POST.get("password")
if username == "joy" and password == "123456":
return HttpResponse("login success...")
else:
return render(request, "login.html")

访问http://127.0.0.1:8000/app01/login_cbv

[10/Apr/2020 11:35:08] "GET /app01/login_cbv/ HTTP/1.1" 200 456
2.01680588722229
2.00297474861145
[10/Apr/2020 11:35:16] "POST /app01/login_cbv/ HTTP/1.1" 200 16

1.4.3加在类上面

from django.shortcuts import render,redirect,HttpResponse
from django.views import View
import time
from django.utils.decorators import method_decorator
# Create your views here. def timer(func):
def inner(request,*args,**kwargs):
start_time = time.time()
time.sleep(2)
rep = func(request,*args,**kwargs)
end_time = time.time()
print (end_time-start_time)
return rep
return inner #FBV
@timer
def login(request):
if request.method == "GET":
return render(request,"login.html")
else:
username = request.POST.get("username")
password = request.POST.get("password")
if username == "joy" and password == "123456":
return HttpResponse("login success...")
else:
return render(request,"login.html") #CBV
@method_decorator(timer,name="get")
#如果需要给post方法家装饰器,method_decorator(timer,nmae="post"),必须制定name的值,否则报错

class Login(View):
#@method_decorator(timer)
def dispatch(self, request, *args, **kwargs):
obj = super().dispatch(request,*args,**kwargs)
return obj #这里必须返回,否则Httpresponse错误
#@method_decorator(timer)
def get(self,request):
return render(request, "login.html")
def post(self,request):
username = request.POST.get("username")
password = request.POST.get("password")
if username == "joy" and password == "123456":
return HttpResponse("login success...")
else:
return render(request, "login.html")

访问http://127.0.0.1:8000/app01/login_cbv/

2.017592191696167
[10/Apr/2020 11:39:04] "GET /app01/login_cbv/ HTTP/1.1" 200 456
[10/Apr/2020 11:39:10] "POST /app01/login_cbv/ HTTP/1.1" 200 16

在给类加装饰器的时候,也可以使用name=dispatch,也可以,关键是必须有这个类存在

最新文章

  1. IIS 发布 异常信息 AspNetInitClrHostFailureModule 的解决办法
  2. CentOS 7 安装 MySQL
  3. 树莓派保卫战--防止SSH暴力破解
  4. JSONObject与JSONArray的使用
  5. 51nod1627 瞬间移动
  6. JS鼠标滚动事件
  7. HttpContext 讲解
  8. cf B. Flag Day
  9. 用不动点组合子解递归(python实现)
  10. HDU 4720Naive and Silly Muggles热身赛2 1005题(分锐角钝角三角形讨论)
  11. SQL Server 远程链接服务器详细配置
  12. linux 50个常用命令
  13. jwt、session、oauth 异同
  14. PageRank算法实现
  15. 第二篇:用Android Studio编写Hello World
  16. apt-get使用命令
  17. Visual Studio 2013 在使用 razor无智能提示的解决办法
  18. mac使用nvm安装node进行多版本管理
  19. 713. Subarray Product Less Than K
  20. RequestAnimationFrame更好的实现Javascript动画

热门文章

  1. Dynamics CRM报表提示rsProcessingAborted解决方法
  2. Go+gRPC-Gateway(V2) 微服务实战,小程序登录鉴权服务(四):客户端强类型约束,自动生成 API TS 类型定义
  3. OAuth2 Token 一定要放在请求头中吗?
  4. Linux下Matlab的安装
  5. 做个开源博客学习Vite2 + Vue3 (四)实现博客功能
  6. 邮件功能 - yagmail 模块
  7. Ubuntu20.04安装Redis
  8. python正则表达式基本语法
  9. 100多个很有用的JavaScript函数以及基础写法大集合
  10. LA4851餐厅(求好的坐标的个数)