062.Python前段框架Django视图CBV
一 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,也可以,关键是必须有这个类存在
最新文章
- IIS 发布 异常信息 AspNetInitClrHostFailureModule 的解决办法
- CentOS 7 安装 MySQL
- 树莓派保卫战--防止SSH暴力破解
- JSONObject与JSONArray的使用
- 51nod1627 瞬间移动
- JS鼠标滚动事件
- HttpContext 讲解
- cf B. Flag Day
- 用不动点组合子解递归(python实现)
- HDU 4720Naive and Silly Muggles热身赛2 1005题(分锐角钝角三角形讨论)
- SQL Server 远程链接服务器详细配置
- linux 50个常用命令
- jwt、session、oauth 异同
- PageRank算法实现
- 第二篇:用Android Studio编写Hello World
- apt-get使用命令
- Visual Studio 2013 在使用 razor无智能提示的解决办法
- mac使用nvm安装node进行多版本管理
- 713. Subarray Product Less Than K
- RequestAnimationFrame更好的实现Javascript动画
热门文章
- Dynamics CRM报表提示rsProcessingAborted解决方法
- Go+gRPC-Gateway(V2) 微服务实战,小程序登录鉴权服务(四):客户端强类型约束,自动生成 API TS 类型定义
- OAuth2 Token 一定要放在请求头中吗?
- Linux下Matlab的安装
- 做个开源博客学习Vite2 + Vue3 (四)实现博客功能
- 邮件功能 - yagmail 模块
- Ubuntu20.04安装Redis
- python正则表达式基本语法
- 100多个很有用的JavaScript函数以及基础写法大集合
- LA4851餐厅(求好的坐标的个数)