• Django之--视图层


    视图层

    三板斧

    """
    HttpResponse
        返回字符串类型
    render
        返回html页面 并且在返回给浏览器之前还可以给html文件传值
    redirect
        重定向
    """
    # 视图函数必须要返回一个HttpResponse对象  正确   研究三者的源码即可得处结论
    # The view app01.views.index didn't return an HttpResponse object. It returned None instead.
    
    # render简单内部原理
        from django.template import Template,Context
        res = Template('<h1>{{ user }}</h1>')
        con = Context({'user':{'username':'jason','password':123}})
        ret = res.render(con)
        print(ret)
        return HttpResponse(ret)

    JsonResponse对象

    """
    json格式的数据有什么用?
        前后端数据交互需要使用到json作为过渡 实现跨语言传输数据
        ensure_ascii=False
    
    前端序列化
        JSON.stringify()                    json.dumps()
        JSON.parse()                        json.loads()
    """
    import json
    from django.http import JsonResponse
    def ab_json(request):
        user_dict = {'username':'jason好帅哦,我好喜欢!','password':'123','hobby':'girl'}
    
    
        # 先转成json格式字符串
        # json_str = json.dumps(user_dict,ensure_ascii=False)
        # 将该字符串返回
        # return HttpResponse(json_str)
        # 读源码掌握用法
        # return JsonResponse(user_dict,json_dumps_params={'ensure_ascii':False})
        # In order to allow non-dict objects to be serialized set the safe parameter to False.
        
        l = [111,222,333,444,555]
        # return JsonResponse(l,safe=False)  
        # 默认只能序列化字典 序列化其他需要加safe参数    

    form表单上传文件及后端如何操作

    """
    form表单上传文件类型的数据
        1.method必须指定成post
        2.enctype必须换成formdata
    
    request.FILES
    request.FILES.get('file')
    """
    def ab_file(request):
        if request.method == 'POST':
            # print(request.POST)  # 只能获取普通的简直对数据 文件不行
            print(request.FILES)  # 获取文件数据
            # <MultiValueDict: {'file': [<InMemoryUploadedFile: u=1288812541,1979816195&fm=26&gp=0.jpg (image/jpeg)>]}>
            file_obj = request.FILES.get('file')  # 文件对象
            print(file_obj.name)   # 获取文件名
            with open(file_obj.name,'wb') as f:
                for line in file_obj.chunks():  # 推荐加上chunks方法 其实跟不加是一样的都是一行行的读取
                    f.write(line)
    
        return render(request,'form.html')

    request对象方法

    """
    request.method  # 获取标点提交的请求方式
    request.POST    # 获取POST请求数据
    request.GET     # 获取GET请求数据
    request.FILES   # 获取文件
    request.body    # 原生的浏览器发过来的二进制数据  后面详细的讲
    request.path    # 只能拿到路由无法拿到路由后面的参数
    request.path_info  # 和path一样
    request.get_full_path()  # 能过获取完整的url及问号后面的参数 
    """
        print(request.path)  # /app01/ab_file/
        print(request.path_info)  # /app01/ab_file/
        print(request.get_full_path())  # /app01/ab_file/?username=jason

    FBV(function based view)与CBV(class based view)(重点)

    • 视图函数既可以是函数也可以是类
    #CBV
        #CBV路由层:
        url(r'^login/',views.MyLogin.as_view())
    
        视图层:
        from django.views import View
        class MyLogin(View):
            def get(self,request):
                return render(request,'')
    
            def post(self,request):
                return HttpResponse('post方法')
    • CBV内部执行流程
    # CBV本质上也是FBV,同样也是views.函数内存地址
    
    #CBV
    #路由
    url(r'^login/', views.MyLogin.as_views())
    '''
    as_views()是类MyLogin所继承的父类View下的一个类方法
    views.MyLogin.as_views()会优先执行as_views()方法并将MyLogin作为第一个参数传入
    as_views()方法是一个闭包函数,内部嵌套了函数view,并将view的内存地址作为返回值返回
    '''
    # 路由层可变形为:url(r'^login/', views.view)
    # 由此可以判断出CBV与FBV在路由匹配上本质是一样的,都是路由对应函数内存地址
    
    # 后端
    from django.views import View
    class MyLogin(View):
        def get(self, request):
            return render(request, 'login.html')
        def post(self, request):
            return HttpResponse('post请求')
    '''
    view函数在当浏览器访问login时被触发,此时会先产生一个MyLogin的对象绑定给变量self
    
    self.属性,依照面向对象的查找顺序先找自己再找对象所在的类,再找父类依次往上,直到找到为止。
    
    view方法最终会返回一个self.dispatch方法的执行结果
    很显然对象本身以及产生对象的MyLogin类中都没有dispatch方法,只有MyLogin继承的父类View中有
    
    执行父类View下的dispatch方法,会先判断浏览器的请求是否合法。
    如果合法,就会通过getattr反射到MyLogin中对应的方法,
    handler = getattr(self, request.method.lower(), self.http_method_not_allowed)
    getattr(自定义类生成的对象self, 浏览器请求方式的小写, 如果请求不合法就执行第三个参数)
    假设请求为get,handler = MyLogin下的get方法
    假设请求为post,handler = MyLogin下的post方法
    return handler(request, *args, **kwargs)
    handler加括号,自动调用对应的方法执行,也就是实现了与FBV相同的展示效果
    '''
    # 结合源码,细品
    class View(object):
        http_method_names = ['get', 'post', 'put', 'patch', 'delete', 'head', 'options', 'trace']
        
        @classonlymethod
        def as_view(cls, **initkwargs):
            def view(request, *args, **kwargs):
                self = cls(**initkwargs)
                if hasattr(self, 'get') and not hasattr(self, 'head'):
                    self.head = self.get
                self.request = request
                self.args = args
                self.kwargs = kwargs
                return self.dispatch(request, *args, **kwargs)
            return view
        
        def dispatch(self, request, *args, **kwargs):
            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)
        
        def http_method_not_allowed(self, request, *args, **kwargs):
            logger.warning(
                'Method Not Allowed (%s): %s', request.method, request.path,
                extra={'status_code': 405, 'request': request}
            )
            return http.HttpResponseNotAllowed(self._allowed_methods())
  • 相关阅读:
    JavaScript运行机制 Event Loop
    async 函数
    JavaScript Promise 对象
    pc端rest.css
    微信小程序公用样式类
    移动端base.css
    RegExp正则对象匹配规则
    RegExp正则相关方法
    mysql(五)事务
    mysql(四)海量数据优化
  • 原文地址:https://www.cnblogs.com/Tang-Yuan/p/14628363.html
Copyright © 2020-2023  润新知