欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

Django 之视图使用

程序员文章站 2023-11-27 13:20:16
Django 视图详解,QueryDict对象、Get、Pos t等等...

views 视图

视图概述

  • 视图即视图函数,接收web请求并返回web响应的事务处理函数
  • 响应指符合http协议要求的任何内容,包括json,string,html等
  • 本章忽略事务处理,重点在如何处理返回结果上

其他简单视图

  • django.http 给我们提供了很多和HttpResponse类似的简单视图,通过查看django.http 代码我们知道
  • 此类视图使用方法基本类似,可以通过return语句作为直接反馈返回给浏览器
  • Http404为Exception子类,所以需要raise使用

HttpResponse详解

  • 方法
    • init: 使用网页内容实例化HttpResponse对象
    • write(content): 以文件的方式写
    • flush(): 以文件的方式输出缓存区
    • set_cookie(key, value=’’, max_age=None, expires=None): 设置cookie
      • key, value 都是字符串类型
      • max_age 是一个整数,表示在指定秒数后过期
      • expires 是一个datetime或timedelta对象,会话将在这个指定的日期/时间过期,
      • max_age 与 expires 二选一
      • 如果不指定过期时间,则两个星期后过期
    • delete_cookie(key): 删除指的key的Cookie,如果key不存在则什么也不发生

HttpResponseRedirect

  • 重定向,服务器跳转
  • 构造函数的第一个参数用来指定重定向的地址

Request对象

  • Request介绍
    • 服务器接收到http协议的请求后,会根据报文创建HttpResponse对象
    • 视图函数的第一个参数是HttpResponse对象
    • 在django.http 模块中定义了HttpResponse对象的API
  • 属性
    • 下面除非特别说明,属性都是只读的
    • path: 一个字符串,表示请求的页面的完整路径,不包含域名
    • method: 一个字符串,表示请求使用的HTTP方法,常用值包括: ‘GET’, ‘POST’
    • encoding: 一个字符串,表示提交的数据的编码方式
      • 如果为None则表示使用浏览器的默认设置,一般为utf-8
      • 这个属性是可写的,可以通过修改它来修改访问表单数据使用
    • GET: 一个类似于字典的对象,包含get请求方式的所有参数
    • POST: 一个类似于字典的对象,包含post请求方式的所有参数
    • FILES: 一个类似于字典的对象,包含所有的上传文件
    • COOKIES: 一个标准的Python字典,包含所有的cookie,键和值都为字符串
    • session: 一个即可读又可写的类似于字典的对象,表示当前的会话,
      • 只有当Django启用会话的支持时才可用
      • 详细内容见"状态保持"
  • 方法
    • is_ajax(): 如果请求是通过XMLHttpResponse发起的,则返回True

QueryDict对象

  • 定义在django.http.QueryDict
  • request对象的属性GET、POST都是QueryDict类型的对象
  • 与python字典不同,QueryDict类型的对象用来处理同一个键带有多个值的情况
  • 方法get(): 根据键获取值
    • 只能获取键的一个值
    • 如果一个键同时拥有多个值,获取最后一个值
  • 方法getlist(): 根据键获取值
    • 将键的值以列表返回,可以获取一个键的多个值

GET属性

  • QueryDict类型的对象
  • 包含get请求方式的所有参数
  • 与url请求地址中的参数对应,位于?后面
  • 参数的格式是键值对,即key1 = value1
  • 多个参数之间,使用&相连,如key1=value1&key2=value2
  • 键是开发人员定下来的,值是可变的
  • 案例/views/v12_get
def v12_get(request):
    rst = ""
    for k,v in request.GET.items():
        rst += k + '-->' + v
        rst += ','

    return HttpResponse("Get value of Request is {0}".format(rst))

POST属性

  • QueryDict类型的对象
  • 包含post请求方式的所有参数
  • 与form表单中的控件对应
  • 表单中控件必须有name属性, name为键, value为值
    • checkbbox存在一键多值的问题
  • 键是开发人员定下来的,值是可变的
  • 案例/views/v9_post
    • settint 中设置模板位置
    • 设置get页面的urls和函数
    def v9_post(request):
        rst = ''
        for k, v in request.POST.items():
            rst += k + '->' + v
            rst += ','
        return HttpResponse("Get value of POST is {0}".format(rst))
    

手动编写视图

  • 实验目的
    • 利用django快捷函数手动编写视图处理函数
    • 编写过程中理解视图运行原理
  • 分析
    • django把所有请求信息封装入request
    • django通过urls模块把相应请求跟事件处理函数连接起来,并把request作为参数传入
    • 在相应的处理函数中,我们需要完成两部分
      • 处理业务
      • 把结果封装并返回,我们可以使用HttpResponse,同样也可以自己处理此功能
    • 本案例不介绍业务处理,把目光集中在如何渲染结果并返回
  • render(request, template_name[, context][, context_instance][, content_type][, status][, current_app][, dirs][, using])
    • 使用模板和一个给定的上下文环境,返回一个渲染和的HttpResponse对象
    • request: django的传入请求
    • template_name: 模板名称
    • content_instance: 上下文环境
    • 案例参看代码 ruochen_views/teacher_app/views/render_test
    def rander_test(request):
        # 环境变量
        # c = dict()
        rsp = render(request, "render.html")
        # rsp = HttpResponse(request, "render.html")
        return rsp
    
  • render_to_response
    • 根据给定的上下文字典渲染给定模板,返回渲染后的HttpResponse
  • 系统内建视图
    • 系统内建视图,可以直接使用

    • 404

      • default.page_not_found(request, template_name=‘404.html’)
      • 系统引发Http404时触发
      • 默认传递request_path变量给模板,即导致错误的URL
      • DEBUG=True则不会调用404, 取而代之是调试信息
      • 404视图会被传递一个RequestContext对象并且可以访问模板上下文处理器提供的变量(MEDIA_URL等)
    • 500(server error)

      • defaults.server_error(request, template_name=‘500.html’)
      • 需要DEBUG=False,否则不调用
    • 403 (HTTP Forbidden) 视图

      • defaults.permission_denied(request, template_name=‘403.html’)
      • 通过PermissionDenied触发
    • 400 (bad request) 视图

      • defaults.bad_request(request, template_name=‘400.html’)
      • DEBUG=False

基于类的视图

简单说一下基于类的视图

  • 和基于函数的视图的优势和区别:
    • HTTP方法的methode可以有各自的方法,不需要使用条件分支来解决
    • 可以使用OOP技术(例如Mixin)
  • 概述
    • 核心是允许使用不同的实例方法来相应不同的HTTP请求方法,而避开条件分支实现
    • as_view函数昨晚类的可调用入库,该方法创建一个实例并调用dispatch方法,按照请求方法对请求进行分发,如果该
      方法没有定义,则引发HttpResponseNotAllowed
  • 类属性使用
    • 在类定义时直接覆盖
    • 在调用as_view的时候直接昨晚参数使用,例如:
      urlpatterns = [
          url(r'^about/', GreetingView.as_view(greeting="G'day")),
          ]
      
  • 对基于类的视图的扩充大致有三种方法: Mixin, 装饰as_view, 装饰dispatch
  • 使用Mixin
    • 多继承的一种形式,来自弗雷的行为和属性组合在一起
    • 解决多继承问题
    • View的子类只能单继承,多继承会导致不可期问题
    • 多继承带来的问题:
      • 结构复杂
      • 优先顺序模糊
      • 功能冲突
    • 解决方法
      • 规格继承 - java interface
      • 实现继承 - python,ruby
  • 在URLconf中装饰
    from django.contrib.auth.decorators import login_required, permission_required
    from django.views.generic import TemplateView
    
    from .views import VoteView
    
    urlpatterns = [
        url(r'^about/', login_required(TemplateView.as_view(template_name="secret.html"))),
        url(r'^vote/', permission_required('polls.can_vote')(VoteView.as_view())),
    ]
    
    
  • 装饰类
    • 类的方法和独立方法不同,不能直接运用装饰器,需要用methode_decorator进行装饰
      from django.contrib.auth.decorators import login_required
      from django.utils.decorators import method_decorator
      from django.views.generic import TemplateView
      
      class ProtectedView(TemplateView):
          template_name = 'secret.html'
      
          @method_decorator(login_required)
          def dispatch(self, *args, **kwargs):
              return super(ProtectedView, self).dispatch(*args, **kwargs)
      

相关代码

视图篇用到的相关代码如下

  • urls.py
from django.conf.urls import include, url
from django.contrib import admin

from teacher_app import views as v

urlpatterns = [
    # Examples:
    # url(r'^$', 'ruochen_views.views.home', name='home'),
    # url(r'^blog/', include('blog.urls')),

    url(r'^admin/', include(admin.site.urls)),

    url(r'^teacher/', v.teacher),
    url(r'^v2_exp/', v.v2_exception),

    url(r'^v10_1/', v.v10_1),
    url(r'^v10_2/', v.v10_2),
    url(r'^v11_hello/', v.v11, name='v11'),

    url(r'^v12/', v.v12_get),
    url(r'^v9_get/', v.v9_get),
    url(r'^v9_post/', v.v9_post),

    url(r'render_test/', v.rander_test),
    url(r'render2_test/', v.rander2_test),
    url(r'render3_test/', v.rander3_test),

    url(r'render1_to_res/', v.render4_test),

    url(r'^get404/', v.get404),
]

  • views.py
from django.shortcuts import render, render_to_response
from django.http import HttpResponse, Http404, HttpResponseRedirect
from django.core.urlresolvers import reverse
# Create your views here.

def teacher(r):
    return HttpResponse('这是teacher的一个视图')

def v2_exception(r):
    raise Http404
    return HttpResponse('OK')

def v10_1(r):
    return HttpResponseRedirect(reverse('v11'))

def v10_2(r):
    return HttpResponseRedirect(reverse('v11'))

def v11(r):
    return HttpResponse('v11 访问返回')

def v12_get(request):
    rst = ""
    for k,v in request.GET.items():
        rst += k + '-->' + v
        rst += ','

    return HttpResponse("Get value of Request is {0}".format(rst))

def v9_get(request):
    # 渲染一个模板并返回
    return render_to_response('for_post.html')

def v9_post(request):
    rst = ''
    for k, v in request.POST.items():
        rst += k + '->' + v
        rst += ','
    return HttpResponse("Get value of POST is {0}".format(rst))

def rander_test(request):
    # 环境变量
    # c = dict()
    rsp = render(request, "render.html")
    # rsp = HttpResponse(request, "render.html")
    return rsp

def rander2_test(request):
    # 环境变量
    c = dict()

    c['name'] = "ruochen"
    c['name2'] = "ruochen2"
    c['name3'] = "ruochen3"

    rsp = render(request, "render2.html", context=c)
    return rsp

def rander3_test(request):

    from django.template import loader

    # 得到模板
    t = loader.get_template('render2.html')
    print(type(t))

    r = t.render({"name": "ruochen"})
    print(type(r))
    return HttpResponse(r)

def render4_test(request):
    # 反馈回m模板render2.html
    rsp = render_to_response("render2.html", context={"name": "ruochen"})
    return rsp

def get404(request):
    from django.views import defaults
    return defaults.page_not_found(request, template_name="render.html")
  • templates
    • for_post.html
    <html>
    <head>
        <title>Title</title>
    </head>
    <body>
    <form method="post" action="/v9_post/">
        姓名: <input type="text" name="uname"/><br>
        密码: <input type="password" name="upwd"/><br>
        性别: <input type="radio" name="ugender" value="1"/><input type="radio" name="ugender" value="0"/><br>
        爱好: <input type="checkbox" name="uhobby" value="恰饭"/>恰饭
        <input type="checkbox" name="uhobby" value="跳楼"/>跳楼
        <input type="checkbox" name="uhobby" value="喝酒"/>喝酒
        <input type="checkbox" name="uhobby" value="跳楼"/>爬山<br>
        <input type="submit" value="提交"/>
    </form>
    </body>
    </html>
    
    • render.html
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>
    
    <h1>Render example by ruochen</h1>
    
    </body>
    </html>
    
    • render2.html
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>
    
    <h1>WebPage for rander with {{name}}</h1>
    
    </body>
    </html>
    
  • settings.py
"""
Django settings for ruochen_views project.

Generated by 'django-admin startproject' using Django 1.8.

For more information on this file, see
https://docs.djangoproject.com/en/1.8/topics/settings/

For the full list of settings and their values, see
https://docs.djangoproject.com/en/1.8/ref/settings/
"""

# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
import os

BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))


# Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/1.8/howto/deployment/checklist/

# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = 'a^-vz9v!e2ks%m=d*&fu$r)qc42vpgkqny9jl36plg$(3jtp#q'

# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True

ALLOWED_HOSTS = ["*"]


# Application definition

INSTALLED_APPS = (
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'teacher_app',
)

MIDDLEWARE_CLASSES = (
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    # 'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.auth.middleware.SessionAuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
    'django.middleware.security.SecurityMiddleware',
)

ROOT_URLCONF = 'ruochen_views.urls'

TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [os.path.join(BASE_DIR, "templates")],
        'APP_DIRS': True,
        'OPTIONS': {
            'context_processors': [
                'django.template.context_processors.debug',
                'django.template.context_processors.request',
                'django.contrib.auth.context_processors.auth',
                'django.contrib.messages.context_processors.messages',
            ],
        },
    },
]

WSGI_APPLICATION = 'ruochen_views.wsgi.application'


# Database
# https://docs.djangoproject.com/en/1.8/ref/settings/#databases

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
    }
}


# Internationalization
# https://docs.djangoproject.com/en/1.8/topics/i18n/

LANGUAGE_CODE = 'en-us'

TIME_ZONE = 'UTC'

USE_I18N = True

USE_L10N = True

USE_TZ = True


# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/1.8/howto/static-files/

STATIC_URL = '/static/'

本文地址:https://blog.csdn.net/qq_29339467/article/details/107057031