首页 > 其他分享 >django之视图层

django之视图层

时间:2022-12-13 20:44:37浏览次数:49  
标签:return self request 视图 django json view cls

目录

django之视图层

视图层必会三板斧

用来处理请求的视图函数都必须返回HttpResponse对象
1. return HttpResponse()  # HttpResponse本身是一个类,类加括号产生对象

2. return render()  
    源码见图二,render的源码是一个函数,返回值是HttpResponse(content, content_type, status),产生的也是HttpResponse对象

3. return redirect()  
    源码见图二,redirect的源码是一个函数,里面写了一个三元表达式 
    redirect_class = HttpResponsePermanentRedirect if permanent else HttpResponseRedirect
    产生的结果都是HttpResponse,那么其返回值也是HttpResponse对象

图二

image

JsonResponse对象

正常情况下我们要给浏览器返回一个json格式的字符串需要先把字符串转为json格式然后再发送给浏览器
django中有一个JsonResPonse对象它可以直接完成上面的操作\
下面的是JsonResponse的源码
class JsonResponse(HttpResponse):
    def __init__(self, data, encoder=DjangoJSONEncoder, safe=True,
                 json_dumps_params=None, **kwargs):
        if safe and not isinstance(data, dict):
            raise TypeError(
                'In order to allow non-dict objects to be serialized set the '
                'safe parameter to False.'
            )
        if json_dumps_params is None:
            json_dumps_params = {}
        kwargs.setdefault('content_type', 'application/json')
        data = json.dumps(data, cls=encoder, **json_dumps_params)
        super().__init__(content=data, **kwargs)
1.使用JsonResponse传汉字,加一个json_dumps_params = {'ensure_ascii': False}
    其它的一些可能需要使用到的参数如果没有默认的可以使用json_dumps_params
2.针对非字典的其它可以被序列化的数据需要修改safe参数为False  safe=False

from django.http import JsonResponse
def index(request):
    a = {'name': 'jason老师'}
    b = [1, 2, 3, 4]
    # return JsonResponse(a, json_dumps_params={'ensure_ascii': False})
    return JsonResponse(b, json_dumps_params={'ensure_ascii': False}, safe=False)

request对象获取文件

form表单携带文件需要做到以下几点
    1.method必须是post
    2.enctype必须是multipart/form-data  
    # 在form表单中修改enctype参数为multipart/form-data,默认是application/x-www-form-urlencoded
django后端需要通过request.FILES来获取文件类型的数据,获取到的是一个文件对象
接收文件和GET、POST一样用get
file_obj = request.FILES.get('file')
file_obj.name  # 获取文件名
# 文件对象支持for循环一行行读取文件内容

FBV与CBV

FBV  基于函数的视图
    def index(request): return HttpResponse对象
    
CBV  基于类的视图
    from diango import views
    class MyLoginView(views.View):
        def get(self, request):
            return HttpResponse('from CBV get function')
        
        def post(self, request):
            return HttpResponse('from CBV post function')
    path('login/', views.MyLoginView.as_view())
    使用CBV会根据请求方法的不同自动匹配对应的方法并执行

CBV源码解析

1.先看路由匹配
    path('login/', views.MyLoginView.as_view())
        1.MyLoginView使我们自己定义的类,类点一个名字涉及到名字的查找顺序,自己没有往父类找
        2.类名点名字加括号调用表明是一个绑定给类的方法(@classmethod)
2.函数名或方法名加括号执行优先级最高,项目一启动就会自动最先执行as_view方法
    通过查看源码可以看到as_view方法的返回值是定义在as_view内部的view方法,那么我们的路由匹配就可以看成是
    path('login/', views.view)  # 由此可以看出CBV的本质还是FBV
    源码:
        @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)
                    if hasattr(self, 'get') and not hasattr(self, 'head'):
                        self.head = self.get
                    self.setup(request, *args, **kwargs)
                    if not hasattr(self, 'request'):
                        raise AttributeError(
                            "%s instance has no 'request' attribute. Did you override "
                            "setup() and forget to call super()?" % cls.__name__
                        )
                    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
3.由第二步可以得到浏览器访问login路由需要执行view函数
    1.执行view函数会产生一个我们自己编写的类的对象
    2.这个对象会调用dispatch方法
    源码:
        def view(request, *args, **kwargs):
        self = cls(**initkwargs)  # cls是我们自己编写的类,这一步是产生一个我们自己编写的类的对象
        if hasattr(self, 'get') and not hasattr(self, 'head'):
            self.head = self.get
        self.setup(request, *args, **kwargs)
        if not hasattr(self, 'request'):
            raise AttributeError(
                "%s instance has no 'request' attribute. Did you override "
                "setup() and forget to call super()?" % cls.__name__
            )
        return self.dispatch(request, *args, **kwargs)  # 我们自己编写的类的对象调用dispath方法
4.由于我们自己编写的类中没有dispatch方法,所以从父类中找
    通过研究父类中的dispatch方法可以知道该方法是获取当前的请求方法并转小写,然后利用反射获取类中对应的方法并执行
    源码:
            def dispatch(self, request, *args, **kwargs):
            # 判断转小写之后的请求方法是不是属于八个正常的请求方法
                if request.method.lower() in self.http_method_names:
                    # getattr(对象,'get', '获取不到的报错信息')
                    handler = getattr(self, request.method.lower(), self.http_method_not_allowed)
                else:
                    handler = self.http_method_not_allowed
                return handler(request, *args, **kwargs)  # 执行反射之后获取到的方法

标签:return,self,request,视图,django,json,view,cls
From: https://www.cnblogs.com/zyg111/p/16980563.html

相关文章

  • django模板层
    目录django模板层模板语法传值模板语法传值特性模板语法之过滤器(内置函数)django模板层模板语法传值1.精准传值returnrender(request,'01.html',{'a':name,'......
  • django 4 视图层
    今日内容详细目录今日内容详细视图层视图层之三板斧JsonResponse对象视图层之request对象获取文件视图层之FBV与CBVCBV源码剖析模板层模板语法之传值操作模板语法之传值特......
  • 视图层
    昨日内容回顾数据增删改查可视化界面1.request对象方法 request.GET\request.POST\request.method2.数据库迁移命令 makemigrations\migrate3.form表单提交数据......
  • Django4
    路由分发1.django是专注于开发应用的,当一个django项目特别庞大的时候,所有的路由与视图函数映射关系全部写在项目名下urls.py(总路由),很明显太冗余也不便于管理,这个时候也......
  • django框架(部分讲解)
    路由分发django每个应用都可以有自己独立的路由层、静态文件、模板层。基于该特性多人开发项目就可以完全解耦合,之后利用路由分发还可以整合到一起多个应用都有很多路由......
  • python之路48 django 视图层、模板层
    视图层之必会三板斧用来处理请求的视图函数都必须返回HttpResponse对象完全正确classHttpResponse:passreturnHttpResponse()defrender():returnH......
  • django 视图层
    简介:视图层三板斧详解,JsonResponse对象,request对象获取文件,FBV与CBV,CBV源码剖析目录视图层视图层三板斧详解JsonResponse对象request对象获取文件FBV与CBVFBVCBV源码剖析......
  • django之路由分发,名称空间,虚拟环境,视图层之必备三板斧,JsonResponse对象,视图层之reques
    路由分发应用场景:1、Django的每一个应用都可以有自己的templates文件夹,urls.py、static文件夹,正是基于这个特点,Django能够非常好的做到分组开发(每个人只写自己的app),公......
  • django之视图层
    目录视图层之必会三板斧JsonResponse对象视图层之request对象获取文件视图层之FBV与CBVCBV源码剖析(重要)视图层之必会三板斧用来处理请求的视图函数都必须返回HttpRespo......
  • django之模板层
    模板层模板层的两种语法:"""{{}}:主要与数据值相关{%%}:主要与逻辑相关django的模板语法是自己写的与jinja2不一样1.针对需要加括号调用的名字,django模板语法会自......