zoukankan      html  css  js  c++  java
  • 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)
  • 相关阅读:
    周末之个人杂想(十三)
    PowerTip of the DaySorting Multiple Properties
    PowerTip of the DayCreate Remoting Solutions
    PowerTip of the DayAdd Help to Your Functions
    PowerTip of the DayAcessing Function Parameters by Type
    PowerTip of the DayReplace Text in Files
    PowerTip of the DayAdding Extra Information
    PowerTip of the DayPrinting Results
    Win7下IIS 7.5配置SSAS(2008)远程访问
    PowerTip of the DayOpening Current Folder in Explorer
  • 原文地址:https://www.cnblogs.com/zouzou-busy/p/11185606.html
Copyright © 2011-2022 走看看