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

    一、JsonResponse对象

    1.JsonRespon

    class JsonResponse(data, encoder=DjangoJSONEncoder, safe=True, json_dumps_params=None, **kwargs)

    是HttpResponse的一个子类(有很多的子类),用于帮助创建JSON编码的响应。他从父类继承大部分行为,并具有以下的不同点:

      它的默认Content-Type头部设置为application/json。

    (1)它的第一个参数 data,应该为一个 dict 实例。如果 safe 参数设置为 False,它可以是任何可 JSON 序列化的对象。

    (2)encoder,默认为 django.core.serializers.json.DjangoJSONEncoder,用于序列化data。

    (3)布尔参数 safe 默认为 True。如果设置为 False,可以传递任何对象进行序列化(否则,只允许 dict 实例)。如果 safe 为 True,而第一个参数传递的不是 dict 对象,将抛出一个TypeError。

    (4)json_dumps_params 是一个字典,它是在生成响应时,传给 json.dumps() 的参数。

    2.用法

    from django.http import JsonResponse  
     response = JsonResponse({'foo': 'bar'})  
     response.content  
    '{"foo": "bar"}'      //<span style=" font-family: Helvetica, Tahoma, Arial, sans-serif;">序列化非字典对象</span>

    若要序列化非 dict 对象,你必须设置 safe 参数为 False:

    response = JsonResponse([1, 2, 3], safe=False)  
    如果不传递safe=False,将抛出一个TypeError。 

    3.修改默认的JSON 编码器

     如果你需要使用不同的 JSON 编码器类,你可以传递 encoder 参数给构造函数:

    response = JsonResponse(data, encoder=MyJSONEncoder)  

    JsonResponse(book_list,safe=False,json_dumps_params={"ensure_ascii":False})

    可以解决编码问题,得到想输出的中文了

    二、Form表单上传文件

    def upload(request):
        """
        保存上传文件前,数据需要存放在某个位置。默认当上传文件小于2.5M时,django会将上传文件的全部内容读进内存。从内存读取一次,写磁盘一次。
        但当上传文件很大时,django会把上传文件写到临时文件中,然后存放到系统临时文件夹中。
        :param request: 
        :return: 
        """
        if request.method == "POST":
            # 从请求的FILES中获取上传文件的文件名,file为页面上type=files类型input的name属性值
            filename = request.FILES["file"].name
            # 在项目目录下新建一个文件
            with open(filename, "wb") as f:
                # 从上传的文件对象中一点一点读
                for chunk in request.FILES["file"].chunks():
                    # 写入本地文件
                    f.write(chunk)
            return HttpResponse("上传OK")
    上传文件示例
    form表单上传文件需要注意的事项
                    1.enctype需要由默认的urlencoded变成formdata
                    2.method需要由默认的get变成post
                    (目前还需要考虑的是 提交post请求需要将配置文件中的csrf中间件注释)
    如果form表单上传文件 后端需要在request.FILES获取文件数据 而不再是POST里面
    
    request.method
    request.GET
    request.POST
    request.FILES
    request.path # 只回去url后缀 不获取?后面的参数
    request.get_full_path() # 后缀和参数全部获取

    三、FBV与CBV

    视图函数并不只是指函数,也可以是类

    FBV(基于函数的视图) 面向函数式编程

    CBV(基于类的视图) 面向对象式编程

    1.FBV

    2.CBV

    CBV源码剖析

    主要源码

                            1.从url入手
                            url(r'^login/',views.MyLogin.as_view())  由于函数名加括号执行优先级最高,所以这一句话一写完会立刻执行as_view()方法
                            
                            @classonlymethod
                            def as_view(cls, **initkwargs):  # cls就是我们自己的写的类 MyLogin
                                def view(request, *args, **kwargs):
                                    self = cls(**initkwargs)  # 实例化产生MyLogin的对象  self = MyLogin(**ininkwargs)
                                    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)  # dispatch返回什么 浏览器就会收到什么
                                    # 对象在查找属性或者方法的时候 你一定要默念 先从对象自己这里找  然后从产生对象的类里面找  最后类的父类依次往后
                                return view
                            
                            通过源码发现url匹配关系可以变形成
                            url(r'^login/',views.view)  # FBV和CBV在路由匹配上是一致的 都是url后面跟函数的内存地址

     

     由于函数名加括号执行优先级最高,所以这一句话一写完会立刻执行as_view()方法

     

     对象在查找属性的时候,先从对象自己这里找,然后从产生对象的类中找,最后类的父类一次往后

    2.当浏览器中输入login 会立刻触发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.
                                        # 我们先以GET为例
                                        if request.method.lower() in self.http_method_names:  # 判断当前请求方法是否在默认的八个方法内
                                            # 反射获取我们自己写的类产生的对象的属性或者方法
                                            # 以GET为例  handler = getattr(self,'get','取不到报错的信息')
                                            # handler = get(request)
                                            handler = getattr(self, request.method.lower(), self.http_method_not_allowed)
                                        else:
                                            handler = self.http_method_not_allowed
                                        return handler(request, *args, **kwargs)  # 直接调用我们自己的写类里面的get方法
                                # 源码中先通过判断请求方式是否符合默认的八个请求方法 然后通过反射获取到自定义类中的对应的方法执行

    四、settings源码剖析

                前提:
                    1.django除了暴露给用户一个settings.py配置文件之外  自己内部还有一个全局的配置文件
                    2.我们在使用配置文件的时候 可以直接直接导入暴露给用户的settings.py也可以使用django全局的配置文件 并且后者居多
                        from django.conf import settings
                    3.django的启动入口是manage.py 

     

     django的启动入口是manage.py 

     

     

  • 相关阅读:
    hashMap put的返回值测试
    mysql java 类型对照 int
    crontab
    Caused by: java.lang.IllegalArgumentException: Modifying queries can only use void or int/Integer as return type!
    Unable to start EmbeddedWebApplicationContext due to missing EmbeddedServletContainerFactory bean
    Spring boot ---- java.lang.NoClassDefFoundError: javax/servlet/ServletContext
    蒙特卡罗算法:模拟
    Linux学习笔记:cut命令
    Linux学习笔记:split切分文件并按规律命名及添加拓展名
    Shell学习笔记:awk实现group by分组统计功能
  • 原文地址:https://www.cnblogs.com/xiongying4/p/11543226.html
Copyright © 2011-2022 走看看