FBV & CBV

FBV & CBV

  • FBV 基于函数的view视图写法--> function based view

  • CBV 基于类的view视图写法 --> class based view

    # urls.py
        # CBV
        url(r'^loginview/', views.LoginView.as_view())
        
    # views.py
    # ################################# CBV(类式视图) ############################################
    from django.views import View  # 导入views包下的View类
    
    
    class LoginView(View):  # 继承View类
        # GET
        def get(self, request):  # 类中get方法对应GET请求
            return render(request, 'loginview.html')
        # POST
        def post(self, request):
            username = request.POST.get('username')
            password = request.POST.get('password')
    
            if username == 'sunny' and password == '123':
                return redirect('/home/')
            else:
                return HttpResponse('用户名不存在或者密码错误!')
    
    • View类dispatch扩展

      from django.shortcuts import render, HttpResponse, redirect
      
      
      # Create your views here.
      
      # ################################# FBV(函数式视图) ############################################
      
      def index(request):  # http相关请求信息--封装--HttpRequest对象-传参-->request
          # request 方法
          if request.method == 'GET':
              print('---------------------GET---------------------')
              print('GET:', request.GET)  # get请求提交的数据
              print('META:', request.META)  # 所有的HTTP请求首部相关信息, 具体的头部信息取决于客户端和服务端
              print('path:', request.path)  # /index/
              print('path_info:', request.path_info)  # /index/返回用户访问的url,不包含域名
              print('full_path:', request.get_full_path())  # /index/?username=Sunny&password=123
              print('body:', request.body)
              return render(request, 'index.html')
      
          else:
              # index.html中,表单form action="", action为空表示从当前路径下提交数据, method="get",method,请求方式:get or post
      
              print('---------------------POST---------------------')
              print('method:', request.method)  # 请求方法:get还是post
              print('body:',
                    request.body)  # 请求体, byte类型, request.POST数据就是从body中取到的.b'username=sunny&password=1234'(socket发送的byte类型对象)
              print('path:', request.path)
              print('path_info:', request.path_info)  # 返回用户访问的url,不包含域名
              print('full_path:', request.get_full_path())
              print('META:', request.META)  # 所有的HTTP请求首部相关信息, 具体的头部信息取决于客户端和服务端
              print('POST:',
                    request.POST)  # 包含所有HTTP POST参数(request.body中的数据封装)的类字典对象,<QueryDict: {'username': ['sunny'], 'password': ['1234']}>
      
              return HttpResponse('Post 请求已响应')
      
      
      # ################ HTTP协议是基于请求响应的协议,一请求对应一响应 ################
      # HTTP协议 -- 应用层协议,下层传输层 -- TCP协议(一收一发),基于流,稳定
      # django和浏览器都封装了socket
      
      # views视图处理的是对于浏览器请求的响应
      # 1.浏览器get请求:/login/
      #   服务器响应: login.html
      # 2.浏览器post请求: {'username':'sunny', 'password':'1234'}
      #   服务器响应: status code:302 not found(重定向状态码), location: /home/
      # 3.浏览器get请求: /home/
      #   服务器响应:home.html
      def login(request):
          if request.method == 'GET':
              return render(request, 'login.html')  # 响应html页面
          else:
              username = request.POST.get('username')
              password = request.POST.get('password')
              if username == 'sunny' and password == '1234':
                  return redirect('/home/')  # 重定向页面, 参数为路径,需要在urls中定义
                  # return render(request, 'home.html')
              else:
                  return HttpResponse('Wrong user name or password!Please Retry!')  # 响应消息
      
      
      # 首页
      def home(request):
          return render(request, 'home.html')
      
      
      # ################################# CBV(类式视图) ############################################
      from django.views import View  # 导入views包下的View类
      
      
      class LoginView(View):  # 继承View类,view中的dispatch方法是反射,调用LoginView实例对象中的反射方法
      	
          	# dispatch方法作用: 分发请求方法到对应的视图方法(通过反射类中的视图方法)
          def dispatch(self, request, *args, **kwargs):  # 重写父类方法,扩展, 有请求都先走这个类方法, 然后通过类方法中的反射调用LoginView中的方法
      
              print(request.method, 'before') # 请求前,请求后,都可以做些其他事
              print('user agent:', request.META.get('HTTP_USER_AGENT'))  # 例如先通过request.META可以判断请求对象是不是浏览器或者其他,做些其他事
      
              ret = super().dispatch(request, *args, **kwargs)  # python3: super()自动把默认的View,self参数传入父类, 等价于super(View, self)
              # 对象调用方法时候,会自动把自身当作参数传入
             # super().dispatch(request, *args, **kwargs) 等价于super().dispatch(super(),request, *args, **kwargs)
      
              print(request.method, 'after')
      
              return ret  # 父类方法返回了值,所以子类重写的方法也必须返回值供父类View方法继续调用
      
          # GET
          def get(self, request):
              return render(request, 'loginview.html')
      
          # POST
          def post(self, request):
              username = request.POST.get('username')
              password = request.POST.get('password')
      
              if username == 'sunny' and password == '123':
                  return redirect('/home/')
              else:
                  return HttpResponse('用户名不存在或者密码错误!')
      
      
原文地址:https://www.cnblogs.com/relaxlee/p/12842967.html