Django中的FBV与CBV
一. FBV
FBV(function based views) 基于函数的视图, 即一个url对应一个视图函数.
1.1 FBV代码示例
urls.py
from django.contrib import admin from django.urls import path from app01 import views urlpatterns = [ path('admin/', admin.site.urls), path('login/',views.login) ]
views.py
from django.shortcuts import render,HttpResponse # Create your views here. def login(request): if request.method == "GET": return render(request,"login.html") else: if request.POST.get("user") == "afly" and request.POST.get("pwd") == "123": return HttpResponse("ok") return render(request, "login.html")
login.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <form action="" method="post"> {% csrf_token %} 用户名:<input type="text" name="user"> 密码:<input type="password" name="pwd"> <input type="submit" value="登录"> </form> </body> </html>
二. CBV
CBV(class based views) 基于类的视图,即在视图里使用类处理请求.
Python是一门面向对象的变成语言, 如果只用函数来开发, 有很多面向对象的优点就用不上了(继承, 多态, 封装). 所以Django在后来加入了Class-Based-View.
可以让我们用类写View,这样做的优点主要下面两种 :
- 提高代码的复用性, 可以使用面向对象的技术, 例如: Mixin(多继承)
- 可以用不同的函数正对不同的HTTP方法处理, 而不是通过很多if判断, 提高代码可读性
2.1 CBV代码示例
urls.py
from django.contrib import admin from django.urls import path from app01 import views urlpatterns = [ path('admin/', admin.site.urls), path('login/', views.LoginView.as_view()), ]
views.py
from django.shortcuts import render,HttpResponse # Create your views here. from django.views import View class LoginView(View): def get(self,request): return render(request,"login.html") def post(self,request): print(request.POST.get("user")) print(request.POST.get("pwd")) return HttpResponse("OK") def delete(self,request): return HttpResponse("delete...")
login.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <form action="" method="post"> {% csrf_token %} 用户名:<input type="text" name="user"> 密码:<input type="password" name="pwd"> <input type="submit"> </form> </body> </html>
2.2 CBV的请求流程及View源码解读
1.假如有用户以get请求访问login, views.py下的LoginView会执行as_view()
2.但是LoginView类没有as_view()方法, 于是去他的父类View中查找.
3.他的父类View有此方法, as_view()中的view被执行:
def view(request): return self.dispatch(request, *args, **kwargs)
4.view中对LoginView实例化成了self,又调用了dispatch
def dispatch(self, request, *args, **kwargs): if request.method.lower() in self.http_method_names: handler = getattr(self, request.method.lower(), self.http_method_not_allowed) else: handler = self.http_method_not_allowed return handler(request, *args, **kwargs)
5.dispatch通过反射来判断LoginView是否有该请求方式的方法, 最后将该方法的执行结果返回