视图 CBV和FBV
这是我参与8月更文挑战的第14天,活动详情查看:8月更文挑战
FBV function based view
就是在视图里使用函数处理请求
CBV class based view
就是在视图里使用类处理请求。
Python是一个面向对象的编程语言,如果只用函数来开发,有很多面向对象的优点就错失了(继承、封装、多态)。所以Django在后来加入了Class-Based-View。可以让我们用类写View。这样做的优点主要下面两种:
1. 提高了代码的复用性,可以使用面向对象的技术,比如Mixin(多继承)
1. 可以用不同的函数针对不同的HTTP方法处理,而不是通过很多if判断,提高代码可读性
1、CBV
from django.views import View
class xxx(View):
def get(self,request):
#专门处理get请求
return response
def post(self,request):
#专门处理post请求
return response
url(r"xx/",xxx.as_view()) # 类名.as_view()执行
as_view()的流程
1. 项目运行时加载urls.py文件,执行类,as_view()方法
2. as_view()执行后,内部定义了一个view函数,并且返回.
3. 请求到来的时候,执行view函数
dispatch方法
# http_method_names = ['get'] #只允许提交的请求方法,内部执行View这个函数的时候,就会先访问这个类,这个http_method_names就会覆盖内部的这个方法
def dispatch(self, request, *args, **kwargs):
print("dispatch执行前的操作")
ret = super().dispatch(request, *args, **kwargs)#其实就是执行View里面内部的dispatch方法
print("dispatch执行后的操作")
return ret
CBV执行get和post方法前会,先执行dispatch方法
2、FBV
# views.py
def register(request):
form_obj = RegForm() # 获取一个空的form
if request.method == "POST":
form_obj = RegForm(request.POST, request.FILES) # 获取的一个有数据的form
if form_obj.is_valid():
# 注册成功
form_obj.save() # 因为继承了ModelForm,所有可以直接保存
return redirect("login")
return render(request, "register.html", {"form_obj": form_obj})
url(r'^register/$', views.register, name="register"),
3、装饰器
3.1 FBV
直接加在函数上就行了
3.2 CBV
需要使用一个装饰器
from django.utils.decorators import method_decorator
method_decorator 是将函数装饰器转换成方法装饰器。
加在方法上
@method_decorator(timer)
def get(self, request): #这样就只能get方法可以用
加在dispatch方法上
@method_decorator(timer) #里面的定义的请求方法都可以用
def dispatch(self, request, *args, **kwargs):
print("dispatch执行前的操作")
ret = super().dispatch(request, *args, **kwargs)#其实就是执行View里面内部的dispatch方法
print("dispatch执行后的操作")
return ret
加在类上
@method_decorator(timer,name="get")
@method_decorator(timer,name="post")
@method_decorator(timer,name="dispatch")
class PublishersAdd(View): #加在类上,可以指定对应的方法
自定义装饰器
装饰器:timer
# 统计时间的装饰器
import time
from functools import wraps
def timer(func):
@wraps(func)
def inner(*args, **kwargs):
"""
inner内部函数
"""
start = time.time()
ret = func(*args, **kwargs)
print("执行一共用时:{}".format(time.time() - start))
return ret
return inner
@timer
def func():
"""
我是func函数
"""
time.sleep(0.5)
print("aaaa")
func()
print(func.__name__) #打印函数名 inner (只有加 @wraps(func),才可以输出func,自己的函数名)
print(func.__doc__) #打印函数中的注释
from functools import wraps
@wraps(func) #加wraps才可以输出自己的函数,和注释,不然会输出内部函数里面的