django -- 视图

视图

视图就是一个python函数或者类,它接受web请求并返回web响应,响应可以是一个字符串或者HTML文件,也可以是一个重定向。无论视图写在哪里,都要返回响应,所以代码写在哪里都无所谓,但是为了规范,大家通常把视图放在项目或者app目录中的views.py文件中

先来看一个简单的视图

from django.shortcuts import render

def index(request):
    return render(request,"index.html")

代码解释:

  • 首先,我们从django.shortcuts里面导入了render类
  • 接着,我们定义了index函数,它就是视图函数,每个视图函数都使用request对象作为第一个参数
  • 最后,这个视图函数会返回一个index.html的文件

CBV

我们之前写的图书管理系统,都是基于函数的view,叫做FBV(function based view),还可以把view写成基于类的,叫做CBV(class based view)

FBV版
def add_press(request):
    if request.method == 'POST':  
        name = request.POST.get('name')  
        Press.objects.create(name=name)  

        return redirect('/press_list/') 

    return render(request,'add_press2.html')  
CBV版
from django.views import View  # 导入View类


class AddPress(View):  # 要继承View类

    def get(self, request):
        return render(request, 'add_press2.html')

    def post(self, request):
        name = request.POST.get('name')
        Press.objects.create(name=name)  
        return redirect('/press_list/')

注意:

使用CBV时,urls.py中也做对应的修改:

url(r'^add_press/', views.AddPress.as_view()),

函数名是固定的,如果是get请求则会执行get方法,如果是post请求,则会执行post方法

CBV的流程:

  • 定义CBV,要继承View类 
  • 修改对应的路由
  • AddPress.as_view()在请求没来之前执行这句,执行完的结果是view(可以去看源码)
  • 当请求到来的时候执行view函数,执行了如下的步骤  

    1. 实例化自己写的类 —— 》self

      self = cls(**initkwargs)

    2. self.request = request

    3. 执行 self.dispatch(request, *args, **kwargs)

      1. 执行父类中的dispatch方法

        1. 判断请求方式是否被允许

          1. 允许的情况

            handler = 通过反射获取 get post 方法

          2. 不允许的情况

            handler = 不允许的方法

          3. handler(request, *args, **kwargs)

      2. 返回HttpResponse对象

    4. 返回HttpResponse对象 给django

CBV使用装饰器

给CBV使用装饰器有三种方法,我们先来写个装饰器,统计一下请求执行所需要的时间

def wrapper(func):
    def inner(*args, **kwargs):
        start_time = time.time()
        ret = func(*args, **kwargs)
        end_time = time.time()
        print("执行时间为:", end_time-start_time)
        return ret
    return inner

如果是给函数使用装饰器,我们直接在函数上面写@wrapper就可以了

第一种方法,给类里的方法加装饰器,如果要给CBV加装饰器,首先要导入django提供的一个类,才能使用

from django.utils.decorators import method_decorator

想给哪个方法使用装饰器,就直接在该方法上面写

@method_decorator(装饰器名)

给get方法加装饰器

from django.utils.decorators import method_decorator

class AddPress(View):  # 要继承view类

    @method_decorator(wrapper)
    def get(self, request):
        print('get')
        return render(request, 'add_press2.html')

    def post(self, request):
        print('post')
        name = request.POST.get('name')
        Press.objects.create(name=name)
        return redirect('/press_list/')

第二种方法:给类加装饰器

@method_decorator(wrapper, name='get')
@method_decorator(wrapper, name='post')
class AddPress(View):  # 要继承view类

    def get(self, request):
        print('get')
        return render(request, 'add_press2.html')

    def post(self, request):
        print('post')
        name = request.POST.get('name')
        Press.objects.create(name=name)
        return redirect('/press_list/')

给类加装饰器必须要有一个name,值为要装饰的方法名。因为要给两个方法都加,所以要写两个

第三种方法:

请求过来后会先执行dispatch()这个方法,如果需要批量对具体的请求处理方法,如get,post等做一些操作的时候,这里我们可以手动改写dispatch方法,这个dispatch方法就和在FBV上加装饰器的效果一样。

from django.utils.decorators import method_decorator

class AddPress(View):  # 要继承view类

    @method_decorator(wrapper)
    def dispatch(self, request, *args, **kwargs):  # 重写dispatch方法
        ret = super().dispatch(request, *args, **kwargs)
        return ret

    def get(self, request):
        print('get')
        return render(request, 'add_press2.html')

    def post(self, request):
        print('post')
        name = request.POST.get('name')
        Press.objects.create(name=name)
        return redirect('/press_list/')

使用第三种方法,我们就给类下面的所有方法都加上了装饰器

Request对象

当一个页面被请求时,Django就会创建一个包含本次请求原信息的HttpRequest对象。

Django会将这个对象自动传递给相应的视图函数,一般视图函数约定俗成地使用 request 参数承接这个对象。

属性
  • request.path_info     返回用户访问url,不包括域名
  • request.method        请求中使用的HTTP方法的字符串表示,全大写表示。
  • request.GET              包含所有HTTP  GET参数的类字典对象
  • request.POST           包含所有HTTP POST参数的类字典对象
  • request.body            请求体,byte类型 request.POST的数据就是从body里面提取到的
  • request.scheme  表示请求方案的字符串(通常为http或https)
  • request.body       一个字符串,代表请求报文的主体。在处理非 HTTP 形式的报文时非常有用,例如:二进制图片、XML,Json等。但是,如果要处理表单数据的时候,推荐还是使用 HttpRequest.POST 
  • request.path          一个字符串,表示请求的路径组件(不含域名)
  • request.encoding                 一个字符串,表示提交的数据的编码方式(如果为 None 则表示使用 DEFAULT_CHARSET 的设置,默认为 'utf-8')。
  • request.COOKIES               一个标准的Python 字典,包含所有的cookie。键和值都为字符串
  • request.FILES                     一个类似于字典的对象,包含所有的上传文件信息。FILES 中的每个键为<input type="file" name="" /> 中的name,值则为对应的数据。注意,FILES 只有在请求的方法为POST 且提交的<form> 带有enctype="multipart/form-data" 的情况下才会包含数据。否则,FILES 将为一个空的类似于字典的对象
  • request.META                  一个标准的Python 字典,包含所有的HTTP 首部。具体的头部信息取决于客户端和服务器,
    request.META.get('REMOTE_ADDR')获取客户端的IP
  • request.user                    一个 AUTH_USER_MODEL 类型的对象,表示当前登录的用户。如果用户当前没有登录,user 将设置为 django.contrib.auth.models.AnonymousUser 的一个实例。你可以通过 is_authenticated() 区分它们
  • request.session               一个既可读又可写的类似于字典的对象,表示当前的会话。只有当Django 启用会话的支持时才可用
方法
  • request.get_host()            返回IP地址和端口
  • request.get_full_path()     返回 path,可以将加上查询字符串。
  • request.is_secure()           如果请求时是安全的,则返回True;即请求通是过 HTTPS 发起的
  • request.is_ajax()                如果上ajax发送的,则为True

Response对象

与由Django自动创建的HttpRequest对象相比,HttpResponse对象是我们的职责范围了。我们写的每个视图都需要实例化,填充和返回一个HttpResponse

属性

  • HttpResponse.content:响应内容
  • HttpResponse.charset:响应内容的编码
  • HttpResponse.status_code:响应的状态码

JsonResponse对象

如果我们使用HttpResponse想返回一个字典,直接返回的话,页面上只能看到字典的key,这时候可以使用json.dumps()转化为字符串返回给页面,而Django提供了我们一个方法,可以直接返回字典,类型是json

首先需要导入

from django.http import JsonResponse
def json_data(request):
    dic = {'name':'zouzou', 'age':'18'}
    # return HttpResponse(dic)
    return JsonResponse(dic)

这时候返回的Content-Type:application/json

默认只能传递字典类型,如果要传递非字典类型需要设置一下safe关键字参数。

response = JsonResponse([1, 2, 3], safe=False)

 

posted @ 2019-07-14 22:36  邹邹很busy。  阅读(184)  评论(0编辑  收藏  举报