乔克视界 乔克视界
首页
  • 运维
  • 开发
  • 监控
  • 安全
  • 随笔
  • Docker
  • Golang
  • Python
  • AIOps
  • DevOps
  • 心情杂货
  • 读书笔记
  • 面试
  • 实用技巧
  • 博客搭建
友链
关于
收藏
  • 分类
  • 标签
  • 归档

乔克

云原生爱好者
首页
  • 运维
  • 开发
  • 监控
  • 安全
  • 随笔
  • Docker
  • Golang
  • Python
  • AIOps
  • DevOps
  • 心情杂货
  • 读书笔记
  • 面试
  • 实用技巧
  • 博客搭建
友链
关于
收藏
  • 分类
  • 标签
  • 归档
  • Docker

  • Golang

  • AIOps

  • Python

    • 基础知识

    • Django框架

      • Django之框架
      • Django之ORM详解
      • Django之操作ORM
      • Django之操作ORM例子
      • Django之路由系统
      • Django之跨站请求伪造
      • Django之Cookie和Session
      • Django之CBV和FBV
        • CBV
          • CBV 加装饰器
          • CSRF 在 CBV 上使用
        • FBV
      • Django之中间件
      • Django之用户认证系统
      • Django之Form组件
      • Django之Ajax
      • Django之模板语言
      • Django之URL分发
      • Django中的缓存
      • Models迁移原理
      • 自定义组件Xadmin
      • Markdown 富文本插件
      • 手写一个验证码
    • 其他

  • DevOps

  • 专栏
  • Python
  • Django框架
乔克
2025-07-19
目录

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

注意:

使用 CBV 时,urls.py 中也做对应的修改:

## urls.py中
url(r'^add_class/$', views.AddClass.as_view()),
1
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

要在 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. 加在 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

因为 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

# 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

或者

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

# 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

作者:乔克

本文链接:https://jokerbai.com

版权声明:本博客所有文章除特别声明外,均采用 署名-非商业性-相同方式共享 4.0 国际 (CC-BY-NC-SA-4.0) 许可协议。转载请注明出处!

上次更新: 2025/07/19, 11:33:23
Django之Cookie和Session
Django之中间件

← Django之Cookie和Session Django之中间件→

最近更新
01
使用 Generic Webhook Trigger 触发 Jenkins 多分支流水线自动化构建
07-19
02
使用Zadig从0到1实现持续交付平台
07-19
03
基于Jira的运维发布平台
07-19
更多文章>
Theme by Vdoing | Copyright © 2019-2025 乔克 | MIT License | 渝ICP备20002153号 |
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式