• django视图层


    HttpResponse,render,redirect

    
    ## HttpResponse()
    括号内直接跟一个具体的字符串作为响应体
    
    
    ## render()
    """
    render(request, template_name[, context])
    
    参数:
        1、request:用于生成响应的请求对象,固定必须传入的第一个参数
        2、template_name:要使用的模板的完整名称,必须传入,render默认会去templates目录下查找模板文件
        3、context:可选参数,可以传入一个字典用来替换模块文件中的变量
    
    render:返回html页面 并且在返回给浏览器之前还可以给html文件传值。
    """
    
    ## render简单内部原理
    from django.shortcuts import render,redirect,HttpResponse,reverse
    
    def index(request):
        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)
    
    
    ## redirect()
    """
    返回重定向信息
    """
    def my_view(request):
        ...
        return redirect('/some/url/')
    
    # 重定向的地址也可以是一个完整的URL:
    def my_view(request):
        ...
        return redirect('http://www.baidu.com/') 
    
    

    JsonResponse对象

    
    ## 向前端返回json数据第一种方式
    import json
    def my_view(request):
        data=['egon','kevin']
        return HttpResponse(json.dumps(data, ensure_ascii=False) )
    
    ## 向前端返回json数据第二种方式
    from django.http import JsonResponse
    def ab_json(request):
    
        # 读源码掌握用法(JsonResponse内部调用json.dumps())
        return JsonResponse(user_dict,json_dumps_params={'ensure_ascii':False})
    
        # 当数据不是字典时要加safe
        # 不加safe报错信息: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=True代表只能序列化字典对象,safe=False代表可以序列化字典以外的对象
    

    form表单上传文件

    """
    form表单上传文件类型的数据
    	1.method必须指定成post
    	2.enctype必须换成multipart/form-data
    
    ## form.html
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <link href="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/css/bootstrap.min.css" rel="stylesheet">
        <script src="https://cdn.bootcss.com/jquery/3.3.1/jquery.min.js"></script>
        <script src="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/js/bootstrap.min.js"></script>
    </head>
    <body>
    <form action="" method="post" enctype="multipart/form-data">
        <p>username:<input type="text" name="username"></p>
        <p>file:<input type="file" name="file"></p>
        <input type="submit">
    </form>
    </body>
    </html>
    """
    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
    request.GET
    request.FILES # 获取文件数据
    request.body  # 原生的浏览器发过来的二进制数据  后面详细的讲
    request.path  # 获取完整的url路径
    request.path_info # 获取完整的url路径
    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与CBV

    视图函数既可以是函数也可以是类

    
    # FBV(function base view)
    ## 我们平常在写django时一直使用的都是FBV
    def index(request):
      return HttpResponse('index')
    
    
    # CBV(class base view)
    ## urls.py
    urlpatterns = [
        # CBV路由
        url(r'^login/',views.MyLogin.as_view()) # 必须调用类下的方法as_view
    ]
    
    ## views.py
    from django.views import View
    
    ## 能够直接根据请求方式的不同直接匹配到对应的方法执行
    class MyLogin(View):
        def get(self,request):
              return render(request,'form.html')
    
        def post(self,request):
              return HttpResponse('post方法')
    

    CBV源码剖析

    ## urls.py
    urlpatterns = [
        # CBV路由
        url(r'^login/',views.MyLogin.as_view())
        ## 相当于 url(r'^login/',views.view)
    ]
    """
    as_view()
        要么是被@staicmethod修饰的静态方法
        要么是被@classmethod修饰的类方法
    """
    
    
    ## views.py
    from django.views import View
    
    class MyLogin(View):
        def get(self,request):
            return render(request,'form.html')
    
        def post(self,request):
            return HttpResponse('post方法')
    
    
    ## 源码
    class View(object):
    
        http_method_names = ['get', 'post', 'put', 'patch', 'delete', 'head', 'options', 'trace']
    
        @classonlymethod
        def as_view(cls, **initkwargs):
            """
            Main entry point for a request-response process.
            """
            for key in initkwargs:
                if key in cls.http_method_names:
                    raise TypeError("You tried to pass in the %s method name as a "
                                    "keyword argument to %s(). Don't do that."
                                    % (key, cls.__name__))
                if not hasattr(cls, key):
                    raise TypeError("%s() received an invalid keyword %r. as_view "
                                    "only accepts arguments that are already "
                                    "attributes of the class." % (cls.__name__, key))
    
            def view(request, *args, **kwargs):
                self = cls(**initkwargs) # self = MyLogin(**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)
                """
                对象属性查找顺序:先从对象自己找--->再去产生对象的类里面找--->之后再去父类找
                """
            view.view_class = cls
            view.view_initkwargs = initkwargs
    
            # take name and docstring from class
            update_wrapper(view, cls, updated=())
    
            # and possible attributes set by decorators
            # like csrf_exempt from dispatch
            update_wrapper(view, cls.dispatch, assigned=())
            return 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)
                """
                handler = getattr(自己写的类产生的对象,要获取的属性或方法,当属性或方法没有的时候就会用第三个参数)
                """
            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())
    
  • 相关阅读:
    ubuntu下手动安装autoconf
    解决VMware下的ubuntu桌面鼠标键盘失效的问题
    DP搬运工1
    把数字转换成货币格式
    指定字符隐藏
    JS 时间获取 (常用)
    electron 安装
    el-form表单校验包含循环
    算法-07| 动态规划
    纯手撸——归并排序
  • 原文地址:https://www.cnblogs.com/chenwenyin/p/12974262.html
Copyright © 2020-2023  润新知