Django之CBV和FBV
# CBV
CBV:class base view,也就是类视图。如下形式:
from django.views import View
class AddClass(View):
## get请求
def get(self, request):
return render(request, "add_class.html")
## post请求
def post(self, request):
class_name = request.POST.get("class_name")
models.Classes.objects.create(name=class_name)
return redirect("/class_list/")
1
2
3
4
5
6
7
8
9
10
11
12
13
14
2
3
4
5
6
7
8
9
10
11
12
13
14
注意:
使用 CBV 时,urls.py 中也做对应的修改:
## urls.py中
url(r'^add_class/$', views.AddClass.as_view()),
1
2
2
# CBV 加装饰器
## 装饰器
def check_login(func):
@wraps(func)
def inner(request, *args, **kwargs):
## 获取cookie
get_cookie = request.get_signed_cookie("is_login", salt="login", default=None)
next_url = request.path_info
if get_cookie == "123":
return func(request, *args, **kwargs)
else:
return redirect("/login/?next={}".format(next_url))
return inner
class LoginView(View):
def get(self, request):
"""
处理GET请求
"""
return render(request, 'login.html')
def post(self, request):
"""
处理POST请求
"""
user = request.POST.get('user')
pwd = request.POST.get('pwd')
if user == 'alex' and pwd == "alex1234":
next_url = request.GET.get("next")
## 生成随机字符串
## 写浏览器cookie -> session_id: 随机字符串
## 写到服务端session:
## {
## "随机字符串": {'user':'alex'}
## }
request.session['user'] = user
if next_url:
return redirect(next_url)
else:
return redirect('/index/')
return render(request, 'login.html')
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
要在 CBV 视图中使用我们上面的 check_login 装饰器,有以下三种方式:
1. 加在 CBV 视图的 get 或 post 方法上
from django.utils.decorators import method_decorator
class HomeView(View):
def dispatch(self, request, *args, **kwargs):
return super(HomeView, self).dispatch(request, *args, **kwargs)
def get(self, request):
return render(request, "home.html")
@method_decorator(check_login)
def post(self, request):
print("Home View POST method...")
return redirect("/index/")
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
2
3
4
5
6
7
8
9
10
11
12
13
14
15
2. 加在 dispatch 方法上
from django.utils.decorators import method_decorator
class HomeView(View):
@method_decorator(check_login)
def dispatch(self, request, *args, **kwargs):
return super(HomeView, self).dispatch(request, *args, **kwargs)
def get(self, request):
return render(request, "home.html")
def post(self, request):
print("Home View POST method...")
return redirect("/index/")
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
2
3
4
5
6
7
8
9
10
11
12
13
14
15
因为 CBV 中首先执行的就是 dispatch 方法,所以这么写相当于给 get 和 post 方法都加上了登录校验。
3. 直接加在视图类上,但 method_decorator 必须传 name 关键字参数
## 如果get方法和post方法都需要登录校验的话就写两个装饰器。
from django.utils.decorators import method_decorator
@method_decorator(check_login, name="get")
@method_decorator(check_login, name="post")
class HomeView(View):
def dispatch(self, request, *args, **kwargs):
return super(HomeView, self).dispatch(request, *args, **kwargs)
def get(self, request):
return render(request, "home.html")
def post(self, request):
print("Home View POST method...")
return redirect("/index/")
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# CSRF 在 CBV 上使用
CSRF Token 相关装饰器在 CBV 只能加到 dispatch 方法上,或者加在视图类上然后 name 参数指定为 dispatch 方法。
备注:
- csrf_protect,为当前函数强制设置防跨站请求伪造功能,即便 settings 中没有设置全局中间件。
- csrf_exempt,取消当前函数防跨站请求伪造功能,即便 settings 中设置了全局中间件。
from django.views.decorators.csrf import csrf_exempt, csrf_protect
from django.utils.decorators import method_decorator
class HomeView(View):
@method_decorator(csrf_exempt)
def dispatch(self, request, *args, **kwargs):
return super(HomeView, self).dispatch(request, *args, **kwargs)
def get(self, request):
return render(request, "home.html")
def post(self, request):
print("Home View POST method...")
return redirect("/index/")
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
或者
from django.views.decorators.csrf import csrf_exempt, csrf_protect
from django.utils.decorators import method_decorator
@method_decorator(csrf_exempt, name='dispatch')
class HomeView(View):
def dispatch(self, request, *args, **kwargs):
return super(HomeView, self).dispatch(request, *args, **kwargs)
def get(self, request):
return render(request, "home.html")
def post(self, request):
print("Home View POST method...")
return redirect("/index/")
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# FBV
FBV:Function Base View,基于函数的视图
例如:
from django.shortcuts import render, HttpResponse, redirect
from orm import models
from utils.mypage import Page
from functools import wraps
from django.views import View
from django.utils.decorators import method_decorator
## Create your views here.
## 装饰器
def check_login_status(func):
@wraps(func)
def inner(request, *args, **kwargs):
## 获取cookie
get_cookie = request.session.get("is_login")
next_url = request.path_info
if get_cookie == "123":
return func(request, *args, **kwargs)
else:
return redirect("/app02/login/?next={}".format(next_url))
return inner
def login(request):
"""用户登录"""
if request.method == "POST":
user = request.POST.get("username")
pwd = request.POST.get("password")
## 获取跳转url
next_url = request.GET.get("next")
check_username = models.Userinfo.objects.filter(username=user)
if check_username:
if pwd == check_username[0].password:
if next_url:
ret = redirect("{}".format(next_url))
else:
ret = redirect("/app02/home/")
## 设置session
request.session["is_login"] = "123"
return ret
return render(request, "app02/login.html")
@check_login_status
def home(request):
return render(request, "app02/home.html")
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
作者:
本文链接:https://jokerbai.com
版权声明:本博客所有文章除特别声明外,均采用 署名-非商业性-相同方式共享 4.0 国际 (CC-BY-NC-SA-4.0) 许可协议。转载请注明出处!
上次更新: 2025/07/19, 11:33:23
- 02
- 使用Zadig从0到1实现持续交付平台07-19
- 03
- 基于Jira的运维发布平台07-19