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)
  • 相关阅读:
    scheme资料
    lisp 资料
    linux input 文章
    qt 键盘驱动分析
    表达式模板 (C++学习)
    qt 键盘插件(mine)
    qt 私有实现导致plugin 加载 提示 undefined symbol
    Visual C++ 8.0对象布局的奥秘:虚函数、多继承、虚拟继承
    linux内核input子系统解析
    qt 键盘 插件
  • 原文地址:https://www.cnblogs.com/zouzou-busy/p/11185606.html
Copyright © 2011-2022 走看看