zoukankan      html  css  js  c++  java
  • Django视图之FBV与CBV

    Django视图之FBV与CBV

     

    一. CBV与FBV

      CBV:Class Based View

      FBV:Function Based View

      我们之前写过的都是基于函数的view,就叫FBV。还可以把view写成基于类的,那就是CBV。

      下面我们就以前面所写的图书管理系统中的添加出版社为例:

      FBV版本:

    `# 新增出版社``def` `add_publisher(request):``    ``if` `request.method ``=``=` `"POST"``:``        ``pub_name ``=` `request.POST.get(``"name"``)``        ``models.Publisher.objects.create(name``=``pub_name)``        ``return` `redirect(``"/publisher_list/"``)``    ``return` `render(request, ``"add_publisher.html"``)`

      CBV版本:

    `from` `django.views ``import` `View`` ` ` ` `class` `AddPublisher(View):``    ``def` `get(``self``, request):``        ``return` `render(request, ``"add_publisher.html"``)`` ` `    ``def` `post(``self``, request):``        ``pub_name ``=` `request.POST.get(``"name"``)``        ``models.Publisher.objects.create(name``=``pub_name)``        ``return` `redirect(``"/publisher_list/"``)`

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

    `path(``'add_publisher/'``, views.AddPublisher.as_view()),  ``# 新增出版社  `

    二. 给视图加装饰器

    1. 使用装饰器装饰FBV

      FBV本身就是一个函数,所以和给普通的函数加装饰器无差:

    def wrapper(func):
      def inner(*args, **kwargs):
          start_time = time.time()
          ret = func(*args, **kwargs)
          end_time = time.time()
          print("used:", end_time - start_time)
          return ret

      return inner


    # 新增出版社
    @wrapper
    def add_publisher(request):
      if request.method == "POST":
          pub_name = request.POST.get("name")
          models.Publisher.objects.create(name=pub_name)
          return redirect("/publisher_list/")
      return render(request, "add_publisher.html")

    2. 使用装饰器装饰CBV

      类中的方法与独立函数不完全相同,因此不能直接将函数装饰器应用于类中的方法 ,我们需要先将其转换为方法装饰器。Django中提供了method_decorator装饰器用于将函数装饰器转换为方法装饰器。

      方式一:给某个方法加上装饰器(此例给get方法加上)

    `from` `django.views ``import` `View``from` `django.utils.decorators ``import` `method_decorator`` ` ` ` `class` `AddPublisher(View):  ``# CBV版``    ``@method_decorator``(wrapper)``    ``def` `get(``self``, request):``        ``return` `render(request, ``"add_publisher.html"``)`` ` `    ``def` `post(``self``, request):``        ``pub_name ``=` `request.POST.get(``"name"``)``        ``models.Publisher.objects.create(name``=``pub_name)``        ``return` `redirect(``"/publisher_list/"``)`

      方式二:加在dispatch方法上面,会给类下的所有方法加上此装饰器

    `class` `AddPublisher(View):  ``# CBV版``    ``@method_decorator``(wrapper)``    ``def` `dispatch(``self``, request, ``*``args, ``*``*``kwargs):``        ``obj ``=` `super``(AddPublisher, ``self``).dispatch(request, ``*``args, ``*``*``kwargs)``        ``return` `obj`` ` `    ``def` `get(``self``, request):``        ``return` `render(request, ``"add_publisher.html"``)`` ` `    ``def` `post(``self``, request):``        ``pub_name ``=` `request.POST.get(``"name"``)``        ``models.Publisher.objects.create(name``=``pub_name)``        ``return` `redirect(``"/publisher_list/"``)`

      方式三:加在类上面

    `@method_decorator``(wrapper, name``=``"post"``)``@method_decorator``(wrapper, name``=``"get"``)  ``# 给哪个方法加,就要指定name``class` `AddPublisher(View):  ``# CBV版``    ``def` `dispatch(``self``, request, ``*``args, ``*``*``kwargs):``        ``obj ``=` `super``(AddPublisher, ``self``).dispatch(request, ``*``args, ``*``*``kwargs)``        ``return` `obj`` ` `    ``def` `get(``self``, request):``        ``return` `render(request, ``"add_publisher.html"``)`` ` `    ``def` `post(``self``, request):``        ``pub_name ``=` `request.POST.get(``"name"``)``        ``models.Publisher.objects.create(name``=``pub_name)``        ``return` `redirect(``"/publisher_list/"``)`

      

     

  • 相关阅读:
    docker 删除所有的 docker ps -a 记录
    使用ES6的Promise完美解决回调地狱
    linux查看历史命令history
    linux命令补全 忘记命令只记得开头
    linux更改shell
    java信号量PV操作 解决生产者-消费者问题
    eclipse代码自动提示功能设置
    linux下mysql修改数据库账户root密码
    IntelliJ Idea12 破解码与中文乱码配置
    linux usermod修改用户所在组方法
  • 原文地址:https://www.cnblogs.com/zengxiaowen/p/11838756.html
Copyright © 2011-2022 走看看