• view视图函数的书写 请求与响应相关


    Django的视图函数view

      一个视图函数(类),简称视图,是一个简单的Python 函数(类),它接受Web请求并且返回Web响应。

      响应可以是一张网页的HTML内容,一个重定向,一个404错误,一个XML文档,或者一张图片。

      无论视图本身包含什么逻辑,都要返回响应。代码写在哪里也无所谓,只要它在你当前项目目录下面。除此之外没有更多的要求了——可以说“没有什么神奇的地方”。为了将代码放在某处,大家约定成俗将视图放置在项目(project)或应用程序(app)目录中的名为views.py的文件中。

    一个简单的视图

      下面是一个以HTML文档的形式返回当前日期和时间的视图:

    from django.http import HttpResponse
    import datetime
    
    def current_datetime(request):
        now = datetime.datetime.now()
        html = "<html><body>It is now %s.</body></html>" % now
        return HttpResponse(html)
    

      让我们来逐行解释下上面的代码:

    • 首先,我们从 django.http模块导入了HttpResponse类,以及Python的datetime库。

    • 接着,我们定义了current_datetime函数。它就是视图函数。每个视图函数都使用HttpRequest对象作为第一个参数,并且通常称之为request

      注意,视图函数的名称并不重要;不需要用一个统一的命名方式来命名,以便让Django识别它。我们将其命名为current_datetime,是因为这个名称能够比较准确地反映出它实现的功能。

    • 这个视图会返回一个HttpResponse对象,其中包含生成的响应。每个视图函数都负责返回一个HttpResponse对象。

      Django使用请求和响应对象来通过系统传递状态。

      当浏览器向服务端请求一个页面时,Django创建一个HttpRequest对象,该对象包含关于请求的元数据。然后,Django加载相应的视图,将这个HttpRequest对象作为第一个参数传递给视图函数。

      每个视图负责返回一个HttpResponse对象。

        img

      视图层,熟练掌握两个对象即可:请求对象(request)和响应对象(HttpResponse)

    CBV和FBV

      FBV(function base views) 就是在视图里使用函数处理请求。

        之前都是FBV模式写的代码,所以就不写例子了。

      CBV(class base views) 就是在视图里使用类处理请求。

      Python是一个面向对象的编程语言,如果只用函数来开发,有很多面向对象的优点就错失了(继承、封装、多态)。所以Django在后来加入了Class-Based-View。可以让我们用类写View。这样做的优点主要下面两种:

    1. 提高了代码的复用性,可以使用面向对象的技术,比如Mixin(多继承)
    2. 可以用不同的函数针对不同的HTTP方法处理,而不是通过很多if判断,提高代码可读性

    书写一个FBV(函数类)

    FBV(function base views) 就是在视图里使用函数处理请求。

    from django.shortcuts import render,HttpResponse,redirect
    def cs(request):
        return redirect('/cs1/')  #重定向  redirect(路径)
    

    书写一个CBV(对象)

    CBV(class base views) 就是在视图里使用类处理请求。

    最后一步源码

     http_method_names = ['get', 'post', 'put', 'patch', 'delete', 'head', 'options', 'trace']
    
    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)
        else:
            handler = self.http_method_not_allowed
        return handler(request, *args, **kwargs)
    

    通过剖析源码 我们可以在分发前执行我们的逻辑

    from django.views import View
    class LoginView(View):
        # def dispatch(self, request, *args, **kwargs):
        #     print('xx请求来啦!!!!')请求来之前  但不知道是什么方法前执行
        #     ret = super().dispatch(request, *args, **kwargs)
        #     print('请求处理的逻辑已经结束啦!!!')
        #     return ret
        def get(self,request):  #处理get请求直接定义get方法,不需要自己判断请求方法了,源码中用dispatch方法中使用了反射来处理的
            print('小小小小')
            return render(request,'login.html')
    
        def post(self,request):
            print(request.POST)
            return HttpResponse('登录成功')
    

    注意类请求 urls.py路由写法

    url(r'^路径/', views.类名.as_view()),
    url(r'^login/', views.LoginView.as_view()),
    

    FBV(函数类) CBV(对象)加装饰器?

    FBV本身就是一个函数,所以和给普通的函数加装饰器无差别
    
    CBV(对象)加装饰器需要先将其转换为方法装饰器。Django中提供了method_decorator装饰器用于将函数装饰器转换为方法装饰器。
    
    代码如下
    

    装饰器装饰FBV

    FBV本身就是一个函数,所以和给普通的函数加装饰器无差

    def wrapper(func):
        def inner(*args, **kwargs):
            start_time = time.time()
            ret = func(*args, **kwargs)
            end_time = time.time()
            print("used:", end_time-start_time)
            return ret
        return inner
    
    
    # FBV版添加班级
    @wrapper
    def add_class(request):
        if request.method == "POST":
            class_name = request.POST.get("class_name")
            models.Classes.objects.create(name=class_name)
            return redirect("/class_list/")
        return render(request, "add_class.html")
    

    装饰器装饰CBV

    类中的方法与独立函数不完全相同,因此不能直接将函数装饰器应用于类中的方法 ,我们需要先将其转换为方法装饰器。Django中提供了method_decorator装饰器用于将函数装饰器转换为方法装饰器。

    第一步先引入模块from django.utils.decorators import method_decorator`
    第2步 加语法糖@method_decorator(wrapper)`
    
    
    from django.shortcuts import render,HttpResponse
    from django.views import View
    from django.utils.decorators import method_decorator
    def wrapper(func):
        def inner(*args, **kwargs):
            print(11111)
            ret = func(*args, **kwargs)
            print(22222)
            return ret
        return inner
    
    # @method_decorator(wrapper,name='get')  # 方式3给get加 用的不多
    class LoginView(View):
    
        @method_decorator(wrapper)  #方式1
        def get(self,request):
            print('小小小小')
            return HttpResponse('登录成功')
    
        def post(self,request):
            print(request.POST)
            return HttpResponse('登录成功')
    

    请求相关:request 对象 属性

    当一个页面被请求时,Django就会创建一个包含本次请求原信息(请求报文中的请求行、首部信息、内容主体等)的HttpRequest对象。
      Django会将这个对象自动传递给响应的视图函数,一般视图函数约定俗成地使用 request 参数承接这个对象。

      当一个页面被请求时,Django就会创建一个包含本次请求原信息的HttpRequest对象。
      Django会将这个对象自动传递给响应的视图函数,一般视图函数约定俗成地使用 request 参数承接这个对象。

      官方文档

    path_info 返回用户访问url,不包括域名
    method 请求中使用的HTTP方法的字符串表示,全大写表示。
    GET 包含所有HTTP GET参数的类字典对象
    POST 包含所有HTTP POST参数的类字典对象
    body 请求体,byte类型 request.POST的数据就是从body里面提取到的
    
    request.method    ——》 请求的方式 8种  GET POST PUT DELETE OPTIONS
            request.GET       ——》 字典  url上携带的参数
            request.POST      ——》 字典  form表单通过POST请求提交的数据
            request.path_info ——》 URL路径 不带参数 
            request.body      ——》 请求体
            request.FILES       上传的文件  {}
            request.COOKIES     cookie
            request.session     session
            request.META            请求头
    

    响应相关:HTTPResponse 对象

    from django.shortcuts import render,HttpResponse,redirect
    HTTPResponse('字符串') #返回字符串
    render(request,'xx.html')#返回html页面
    
    redirect 重定向
    def cs(request):
        return redirect('/cs1/')  #重定向到url为cs1的地址
    
    def cs1(request):
        return HttpResponse('666') #返回字符串666
        
    def cs1(request):
        render(request,'xx.html')#返回html页面
    
  • 相关阅读:
    filter函数和map函数
    生成器面试题
    装饰器激活生成器
    移动平均値
    send()方法的初识
    监听文件的输入
    迭代器抛出异常处理方法
    装饰器-wraps
    多个装饰器装饰一个函数
    WebView 安卓原生java与h5,js交互
  • 原文地址:https://www.cnblogs.com/saoqiang/p/12381793.html
Copyright © 2020-2023  润新知