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
  • 相关阅读:
    根据屏幕宽度适应屏幕样式
    设计模式之命令模式
    动态代理的使用以及其实现机制
    PLSQL链接不上oracle
    struts2自定义结果类型demo
    Tomcat虚拟路径
    SEQUENCE序列
    mysql导出数据库中建表语句和数据
    Tomcat6 启动时 Cannot assign requested address: JVM_Bind
    sql常用命令
  • 原文地址:https://www.cnblogs.com/kenD/p/10066423.html
Copyright © 2011-2022 走看看