视图层

一、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 

 

 

原文地址:https://www.cnblogs.com/xiongying4/p/11543226.html