zoukankan      html  css  js  c++  java
  • 视图系统CBV 和 response

     CBV和FBV

    1. FBV(function based view )

    2. CBV(class based view)

    1. CBV的定义

    # 增加出版社 CBV
    from django.views import View
    
    class AddPublisher(View):
        def get(self, request):
            pass
    
        def post(self, request):
            pass

    2. CBV使用

    url(r'^add_publisher/', views.AddPublisher.as_view()),

    3. CBV的流程

    views.AddPublisher.as_view() 程序加载的时候执行  ——》 view函数

    当请求到来的时候执行view函数:

    1. self = AddPublisher()

    2. self.request = request

    3. 执行self.dispatch方法

      1. 判断请求方式是否被允许

        1. 允许时,通过反射获取到AddPublisher中定义的get或者post方法 ——》handler

        2. 不允许时,self.http_method_not_allowed ——》handler

      2. 执行handler 拿到返回结果 Httpresponse对象

    CBV的匹配原理:

    通过查看View的源码,可以看到里面有很多提交方法

     http_method_names = ['get', 'post', 'put', 'patch', 'delete', 'head', 'options', 'trace']

    使用ajax的时候这些方法都可以使用

    这种根据url 来匹配的方法都是通过反射(getattr)获得的. 请求发过来之后,会先走一个dispatch的方法,这个方法在View类中

    def dispatch(self, request, *args, **kwargs):
        # Try to dispatch to the right method; if a method doesn't exist,
        # defer to the error handler. Also defer to the error handler if the
        # request method isn't on the approved list.
        if request.method.lower() in self.http_method_names:
          handler = getattr(self, request.method.lower(),self.http_method_not_allowed)
        else:
          handler = self.http_method_not_allowed
        return handler(request, *args, **kwargs)
      request.method.lower()

    将请求方式变成小写.  通过反射找到类中的对应方法

    所有的框架,本质都是通过请求方式, 反射不同的函数

    所以CBV的本质,其实还是用的FBV, 只不过用类封装了而已

    4. 给CBV加装饰器 method_decorator

    from django.utils.decorators import method_decorator

           加载到某个get 或者 post的方法上:

    @method_decorator(timer)
    def get(self, request):

        加在self.dispatch方法上:

    @method_decorator(timer)
    def dispatch(self, request, *args, **kwargs):

        加在类上:

    @method_decorator(timer, name='post')
    @method_decorator(timer, name='get')
    class AddPublisher(View):

    5. 区别

    1. 不使用method_decorator

    func: <function AddPublisher.dispatch at 0x00000163735176A8>args :<app01.views.AddPublisher object at 0x00000163735F7EF0> <WSGIRequest: GET '/add_publisher/'>

    1. 使用method_decorator

    func:<function method_decorator.<locals>.dec.<locals>.wrapper.<locals>.bound_func at 0x0000019664B4A378>arsgs: <WSGIRequest: GET '/add_publisher/'>

    简而言之:

    不使用method_decorator的时候, 第二个参数是request

    使用method_decorator的时候, 第一个参数是request

    request对象(常用的) **

    需要记几个常用的request的属性和方法

    print(request.method)   # 请求方式   GET 、POST
    print(request.GET)      # get的请求数据    QueryDict{} url携带参数
    print(request.POST)     # post的请求数据   QueryDict{} form表单提交的post数据
    print(request.path_info)   # 路径信息   不包含IP和端口、参数
    print(request.path) #获取请求路径信息
    print(request.body) #获取的是请求体里的数据

     print(request.FILES) #上传的文件
      上传文件注意事项:
      form表单的enctype:multipart/form-data;
      method="post";
      name="作为键";
      {%csrf_token%};
      取文件对象的方法: chunks();
      request.FILES中获取文件对象

    print(request.is_ajax())       #是否是ajax请求
    print(request.get_host())
    print(request.get_full_path()) # 路径信息 + 参数

    response对象

    1. HttpResponse("字符串") --->字符串
    2. render(request,"模板文件名",{k:v}) ----->完整的页面
    3. redirect("要跳转的地址")---> 本质是响应头:Location:url
            1. ret=HttpResponse()  ret["Location"]=url(设置响应头)
            
    4. JsonResponse({字典})  ContentType:application/json
        1.传非字典类型的时候设置: safe=False

    文件上传 

    view.py

    # 上传文件
    def upload(request):
        if request.method == 'POST':
            # print(request.body)
            file = request.FILES.get('f1')
            with open(file.name, 'wb') as f:
                for chunk in file.chunks():
                    f.write(chunk)
            return HttpResponse('上传成功')
    
        return render(request, 'upload.html')
    
    
    import json
    from django.http import JsonResponse
    
    
    def json_test(request):
        data = {'name': 'alex', 'pwd': 'alexdsb'}
    
        ret = HttpResponse(json.dumps(data))
        ret['Content-Type'] = 'application/json'
        ret['xxx'] = 'axxx'
        return ret
        # return HttpResponse(json.dumps(data), content_type='application/json')  # Content-Type: text/html; charset=utf-8
        # return JsonResponse(data)  # Content-Type: application/json

    template

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>
    <form action="" method="post" enctype="multipart/form-data">
        {% csrf_token %}
        文件:<input type="file"  name="f1">
        <button>上传</button>
    </form>
    </body>
    </html>

    上传文件注意事项:

    1. form表单的enctype = 'multipart/form-data'

    2. request.FILES中获取文件对象

    3. 使用文件对象的chunks()

    JsonResponse 作用是做序列化的 

    服务器--->浏览器

    Contenttype:json

    from django.http import JsonResponse
    
    def json_test(request):
        data = {'name': 'alex', 'pwd': 'alexdsb'}
        
        return JsonResponse(data)  # Content-Type: application/json
        # return HttpResponse(json.dumps(data), content_type='application/json')  # Content-Type: text/html; charset=utf-8
  • 相关阅读:
    记第一场省选
    POJ 2083 Fractal 分形
    CodeForces 605A Sorting Railway Cars 思维
    FZU 1896 神奇的魔法数 dp
    FZU 1893 内存管理 模拟
    FZU 1894 志愿者选拔 单调队列
    FZU 1920 Left Mouse Button 简单搜索
    FZU 2086 餐厅点餐
    poj 2299 Ultra-QuickSort 逆序对模版题
    COMP9313 week4a MapReduce
  • 原文地址:https://www.cnblogs.com/kenD/p/10066423.html
Copyright © 2011-2022 走看看