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页面

猜你喜欢

转载自www.cnblogs.com/saoqiang/p/12381793.html