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数据,未做任何处理
    
  • 相关阅读:
    互斥锁
    信号量、互斥体和自旋锁
    【设计模式】template method(模板方法)-- 类行为型模式5.10
    C/C++中的auto关键词
    【设计模式】observer(观察者)-- 对象行为型模式5.7
    UML图
    MapReduce阅读
    shell提取文件后缀名,并判断其是否为特定字符串
    shell编程--遍历目录下的文件
    Linux shell字符串截取与拼接
  • 原文地址:https://www.cnblogs.com/chiyun/p/14066515.html
Copyright © 2011-2022 走看看