zoukankan      html  css  js  c++  java
  • Django-视图层

    一、视图层之请求对象

    def index(request):
        '''
        request:django封装的对象,它的类是WSGIRequest,它里面包含了所有http请求的东西
        '''
        print(request)
        print(type(request))
        # from django.core.handlers.wsgi import WSGIRequest
       
    
        # 常用方法
        print(request.method)
        print(request.GET)
        print(request.POST)
        print(request.is_ajax()) # 是不是ajax请求
        print(request.path)      # 请求路径 如地址栏为http://127.0.0.1:8000/login/,打印结果为/login/
        print(request.get_full_path()) # 请求全路径,带数据与上一条一样,不过如果是 get请求会带上后面的数据
        print(request.body)      # 请求体,二进制,如果传文件,这个报错
        
        '''
        使用form表单,默认情况下数据被转成name=lqz&password=123放到请求体中
        request.POST其实是从body中取出bytes格式的,转成了字典
        requet.GET其实是把访问路径中?后面的部分拆出来,转成了字典
        '''
        print(request.encoding) # 客户端向服务端传递时,使用的编码方法,如果没有设置,默认使用utf8,但是打印出来会是None。若指定了,就打印指定的编码方式
    
        print(request.META)    # 重点,字典,一堆东西,请求用户的ip地址,请求头中数据,用户自定制请求头的数据
        '''
        META里面把请求头的key值部分统一加HTTP_  并且全部转成大写
        '''
        print(request.META['REMOTE_ADDR'])  # 客户端的ip地址
        print(request.FILES)  # 客户端上传的文件
    
        print(request.COOKIES) # 一个标准的Python 字典,包含所有的cookie。键和值都为字符串。
        print(request.session) # 一个既可读又可写的类似于字典的对象,表示当前的会话。只有当Django 启用会话的支持时才可用。
        print(request.user)    # 匿名用户
        return HttpResponse('ok')
    

    二、视图层之响应对象

    最常用的四种是HttpResponse,render,redirect,JsonResponse。

    重点:JsonResponse的使用(看源码)
    # JsonResponse导入位置和另外三个
    from django.http import JsonResponse导入位置和另外三个
    
    def index(request):
        # 向客户端返回json格式数据
        # django内置提供的JsonResponse,本质还是HttpResponse
        import json
        res=json.dumps({'name':'杨','age':18},ensure_ascii=False)
        return HttpResponse(res)
    
        # ensure_ascii
        return JsonResponse({'name':'杨','age':18},json_dumps_params={'ensure_ascii':False})
        # safe,转换除字典以外的格式,需要safe=False
        return JsonResponse([11,12,13,'yang',[1,2,3],{'name':'yang','age':19}],safe=False)
    

    三、CBV和FBV

    说白了就是把之前函数里的东西写到类里

    1.cbv使用

    # CBV基于类的视图(Class base view)和FBV基于函数的视图(Function base view)
    
    # 写视图类(还是写在views.py中)
    # 第一步,写一个类,继承View
    from django.views import View
    
    class Index(View):
        def get(self, request):  # 当url匹配成功,get请求,会执行它
            return HttpResponse('ok')
    
        def post(self,request):
            return HttpResponse('post')
        
    ## 第二步:配置路由
    path('index/', views.Index.as_view()),
    

    2.cbv的实现本质

    1 请求来了,路由匹配成功执行 path('index/', views.Index.as_view()),
        执行views.Index.as_view()()
    2 本质是执行as_view()内部有个闭包函数view()
    3 之后是view()---》dispatch()
    4 dispatch内部,根据请求的方法(get,post)---->执行视图类中的get,post
    即最终调用的其实是dispatch这个函数,并且我们可以通过重写dispatch函数来对近来的请求做控制
    

    3.源码分析

    image-20201012204048076

    image-20201012204251040

    image-20201012204324212

    4.重写dispatch方法

    def dispatch(self, request, *args, **kwargs):
    
            # 执行原来的dispatch
            # 类似于装饰器
            # 加代码
            res=super().dispatch(request, *args, **kwargs)  
            '''
            在这我们利用super调用父类的dispatch方法,然后我们可以在这个的前后加上代码,实现一个类似装饰器
            '''
            # 加代码
            return res
    
            # 我们可以改变他的return值,实现不管什么请求来,都执行get请求或者post请求
            return self.get(request, *args, **kwargs)
    

    5.CBV加装饰器

    from django.views import View
    from django.utils.decorators import method_decorator
    # 使用登录认证装饰器
    # 用法一
    # @method_decorator(login_auth,name='get')
    # @method_decorator(login_auth,name='post')
    class UserInfo(View):
        # 用法二
        @method_decorator(login_auth)
        def get(self, request, *args, **kwargs):
            return HttpResponse('userinfo get')
        
        
    # 总结:两种用法
    加在类上:@method_decorator(login_auth,name='get')
    加载方法上:@method_decorator(login_auth)
    

    四、form表单

    对于前段页面来说,如果要上传文件,form表单的enctype要设置为form-data.在正常不设置这个参数值时,默认使用urlencoded

    # action
    1 不写,默认向当前地址发送请求
    2 写相对地址,/index/,向当前域(http://127.0.0.1:8000/)的/index/发送请求
    3 写完整地址,http://127.0.0.1:8000/index/,向该地址发送请求(可以向第三方服务发送请求)
    
    # method
    # 1 post:发送post请求(默认编码情况下:以key=value&key=value的形式拼到请求体中)
    # 2 get:发送get请求(以key=value&key=value的形式拼到路径中)
    <form action="/index/" method="post">
        <p>用户名:<input type="text" name="name"></p>
        <p>密码:<input type="text" name="password"></p>
        <p><input type="submit" value="提交"></p>
    </form>
    

    form表单的常用编码格式

    <form action="" enctype="application/x-www-form-urlencoded"></form>  <!--默认的,不写也是用这个-->
    <form action="" enctype="multipart/form-data"></form>				<!--传文件用这个-->
    

    五、前后端交互编码方式

    对应第四部分,前端传过来的数据,我们视图层需要获取并处理。

    1 application/x-www-form-urlencoded---->传普通的数据,form表单默认就是这种---->
    利用request.POST可取出,这个对象类似一个字典,可当成字典
    
    2 multipart/form-data-----》传文件和数据---->
    利用request.POST和request.FILES,数据部分在POST中,文件部分在FILES中,都类似字典
    
    3 json----------》传json格式数据---->
    request.body中取出来自行处理
    

    1.urlencoded编码格式

    <!--index.html-->
    <form action="" enctype="application/x-www-form-urlencoded" method="post">
        <p><input type="text" name="username"></p>
    	  <p><input type="file" name="myfile"></p>
        <p><input type="submit"></p>
    </form>
    
    # view.py
    def index(request):
        print(request.POST)
        print(request.FILES)
        print(request.body)
        return render(request,"index.html")
    
    # 输出
    <QueryDict: {'username': ['1']}>
    <MultiValueDict: {}>
    b'username=1'
    

    2.form-data编码格式

    <!--index.html-->
    <form action="" enctype="application/x-www-form-urlencoded" method="post">
        <p><input type="text" name="username"></p>
        <p><input type="file" name="myfile"></p>
        <p><input type="submit"></p>
    </form>
    
    # view.py
    因为使用form-data编码格式时候,无法同时打印request.POST,request.FILES和request.body,即只能二选一,
    所以下面的输出是分开打印的,这个代码块里我写在一起,但是实际上这三行代码运行就会报错。
    应该request.POST,request.FILES连用或者request.body单独用
    
    def index(request):
        print(request.POST)
        print(request.FILES)
        print(request.body)
        return render(request,"index.html")
    
    # 输出
    <QueryDict: {'username': ['2']}>
    <MultiValueDict: {'myfile': [<InMemoryUploadedFile: 111.jpg (image/jpeg)>]}>
    b'------WebKitFormBoundaryAJB3PRjJlXPjYjoD
    Content-Disposition: form-data; name="username"
    
    2
    
    ------WebKitFormBoundaryAJB3PRjJlXPjYjoD
    Content-Disposition: form-data; name="myfile"; filename="111.jpg"
    Content-Type: image/jpeg
    
    xffxd8xff...一堆bytes...xd9
    
    ------WebKitFormBoundaryAJB3PRjJlXPjYjoD--
    '
    大致能看出来这里面还是包含了数据部分和文件部分的
    

    3.json编码格式

    json格式无法使用form表单传,所以利用postman模拟发送

    image-20201012212802729

    # view.py
    def index(request):
        print(request.POST)
        print(request.FILES)
        print(request.body)
        return render(request,"index.html")
    
    # 输出
    <QueryDict: {}>
    <MultiValueDict: {}>
    b'{"username":3}'
    body中原原本本的放着传过来的json数据,未做任何处理
    
  • 相关阅读:
    021.day21 反射 Class类 反射常用操作
    020.day20 线程概述 多线程优缺点 线程的创建 线程常用方法 生命周期 多线程同步
    019.day19 缓冲流 对象流 标准输入输出流
    018.day18 map集合如何实现排序 File类 IO流 字节流 字符流 编码
    017.day17 Map接口 克隆 treeSet集合排重缺陷
    016.day16 HashSet TreeSet 比较器Comparable Comparator
    015.day15
    014.day14
    013.day13
    线程
  • 原文地址:https://www.cnblogs.com/chiyun/p/14066515.html
Copyright © 2011-2022 走看看