【Django3.2学习】03-视图基础

视图基础

​ Django的视图主要有2种,分别是视图函数视图类,现在我们先从视图函数(FBV)进行入手,后面再学习视图类(CBV)

  • Function BaseView:函数基本视图
  • Class BaseView:类基本视图

一、函数视图

​ Django中所有的函数视图必须编写在子应用的views.py文件中

from django.http.response import HttpResponse


def 函数视图名称(request):
	# 代码
    return HttpResponse("返回内容")

函数视图名称,同一个模块下不能重复,同时采用变量命名规则

参数request解释:

​ Django经过路由调用视图时,会默认传递一个request对象,request对象是http协议的一个代理对象,我们只需要调用request对象的方法就可以拿到我们需要的内容了

二、请求

2.1 限制http请求

​ web项目运行在http协议下,默认肯定也支持用户通过不同的http请求发送数据

常用的http请求:

  • POST:添加/上传
  • GET:获取/下载
  • PUT/PATCH:修改,其中PUT表示修改整体数据,而PATCH表示修改部分数据
  • DELETE:删除/废弃

Django支持让客户端只能通过指定的HTTP请求方式来访问到项目的视图

​ 在子应用home下的views.py下编写如下代码:

# 限制http请求访问视图
def drop(request):
    return HttpResponse(f'删除视图,该方法的请求方式是:{request.method}')  # request.method 获取http请求的方法

​ 在主应用下的urls.py中建立映射关系:

path('drop/', views.drop),

​ 通过浏览器访问http://localhost:8000/drop/,发现此次访问HTTP的请求方式是GET请求

​ 修改视图函数drop:

from django.views.decorators.http import require_http_methods


# 限制http请求访问视图
@require_http_methods(['delete'])
def drop(request):
    return HttpResponse(f'删除视图,该方法的请求方式是:{request.method}')  # request.method 获取http请求的方法

​ 再次通过浏览器访问http://localhost:8000/drop/,发现访问失败,浏览器报错405 Method Not Allowed,那么此时只能通过DETELETE请求来访问drop视图函数。

​ 找到主应用下的settings文件,修改中间件的配置,将'django.middleware.csrf.CsrfViewMiddleware'这一行删除来关闭Csrf。

​ 通过Postman发送DELETE请求至http://localhost:8000/drop/,请求通过

2.2 设置路由绑定视图

​ 目前这种路由视图映射关系全部写在了主应用下的urls.py中,当然这么做是不灵活的,如果当项目庞大了之后,上千个路由映射就要写条映射关系,这样不仅不够灵活,也不够优雅。

​ 在创建项目时,主应用下的urls.py中有这样一段注释:

"""djdemo URL Configuration

The `urlpatterns` list routes URLs to views. For more information please see:
    https://docs.djangoproject.com/en/4.0/topics/http/urls/
Examples:
Function views
    1. Add an import:  from my_app import views
    2. Add a URL to urlpatterns:  path('', views.home, name='home')
Class-based views
    1. Add an import:  from other_app.views import Home
    2. Add a URL to urlpatterns:  path('', Home.as_view(), name='home')
Including another URLconf
    1. Import the include() function: from django.urls import include, path
    2. Add a URL to urlpatterns:  path('blog/', include('blog.urls'))
"""

​ 官方提供了三种路由视图映射关系的绑定:

  • Function views:函数视图
  • Class-based views:类视图
  • Including another URLconf:包含其他的URL配置

​ 这里我们就根据官方提供的第三种方式Including another URLconf来修改当前冗余的urls配置:

  • 根据文档Import the include() function: from django.urls import include, path,首先导入include()函数

    • from django.urls import path, include
  • 添加映射关系Add a URL to urlpatterns: path('blog/', include('blog.urls'))

    • path('home/', include('home.urls')),
  • 将之前子应用home的映射关系迁移到自己应用下

    • 在home应用下新建python文件urls.py
    • 将主应用中的urls.py映射关系迁移到home中的urls.py中

​ 完成后主应用及子应用下的代码:

​ 主应用django下的urls.py:

from django.contrib import admin
from django.urls import path, include

urlpatterns = [
    path('admin/', admin.site.urls),
    path('home/', include('home.urls')),
]

path(‘home/’, include(‘home.urls’)) 的说明:

path(‘子路由所有路由共同的前缀’, include(‘子应用的目录名.urls’)) 的说明:

​ 子应用home下的urls.py:

from django.urls import path
from home import views

urlpatterns = [
    path('hello/', views.index),
    path('drop/', views.drop),
]

之后访问http://localhost:8000/home/hello/进行测试

2.3 视图接收http请求

​ 在http请求和响应过程中,用户往往会在请求过程中发送请求信息给服务端

  • 查询字符串[Query String]

    • 所谓的查询字符串就是url地址上面?号后面的数据,例如:

      http://127.0.0.1:8000/index?name=Abo&pwd=123456

      上面的name=Abo&pwd=123456就是查询字符串

      在Django中可以通过request.GET来获取,注意:GET不是http请求,也就是说,只要地址上有查询字符串,都可以获取

  • 请求体数据

  • 请求头报文信息

  • 上传文件

2.3.1 request对象

​ request对象是当用户请求Django时,由wsgi.py中的application web应用对象,会自动帮我们解析http请求的文本内容,并把对应的内容,赋值给request对象的。request对象是from django.core.handlers.wsgi.WSGIRequest请求处理类的实例对象,WSGIRequest继承自django.http.request.HttpRequest,日常开发中使用到的大部分属性功能其实都是HttpRequest提供的

​ 导入HttpRequest的方式:from django.core.handlers.wsgi import WSGIRequest

2.4 获取查询字符串的参数

2.4.1 准备工作

​ 在子应用home中新增视图函数index2及建立路由映射关系

  • 视图函数:

    def index2(request):
        """ 查看request对象提供的常用属性 """
        print(request)
        print(request.__dir__())  # 列出调用者的类目录(即调用者的所有属性及方法)
        print(request.method)  # 获取本次客户端的http请求方法
        print(request.GET)  # 获取查询字符串参数(即url?号后面拼接的参数),这里的GET是一个方法,被@cached_property装饰器所装饰,是django内部用于优化性能的一种方式
        print(f"name={request.GET['name']}")  # 获取请求字符串中的name参数,直接通过[]的方式取值如果没有这个key会报错
        print(f"pwd={request.GET['pwd']}")  # 获取请求字符串中的pwd参数,直接通过[]的方式取值如果没有这个key会报错
        # url: http://localhost:8000/home/index2/?name=Abo&pwd=123456&like=music&like=book
        print(f"like={request.GET.get('like', None)}")  # 获取请求字符串中的like参数,通过get()方法取值没有不会报错,也可以通过get()方法的第二个参数指定没有参数时的默认值
        print(f"like={request.GET.getlist('like', None)}")  # 获取请求字符串中的like参数列表
    
        return HttpResponse('ok')
    
  • 路由映射

        path('index2/', views.index2),
    
2.4.2 获取查询字符串的方法介绍
  • request.method:获取本次客户端的http请求方法
  • request.GET:获取查询字符串参数(即url?号后面拼接的参数),这里的GET是一个方法,被@cached_property装饰器所装饰,是django内部用于优化性能的一种方式
  • request.GET[‘key’]:获取请求字符串中的key参数,直接通过[]的方式取值如果没有这个key会报错
  • request.GET.get(‘key’, None):获取请求字符串中的key参数,通过get()方法取值没有不会报错,也可以通过get()方法的第二个参数指定没有参数时的默认值
  • like={request.GET.getlist(‘key’, None):获取请求字符串中的key参数列表
2.4.3 QueryDict参数集

​ 视图函数打印request.GET,然后浏览器访问http://localhost:8000/home/index2/?name=Abo&pwd=123456,执行结果如下:

<QueryDict: {'name': ['Abo'], 'pwd': ['123456'], 'like': ['music', 'book']}>

QueryDict说明:

  • QueryDict是参数集对象,类的位置:django.http.QueryDict
  • QueryDict对象继承自MultiValueDict对象,而MultiValueDict对象又继承自dict
  • 完全可以当做使用字典的方式来操作QueryDict

2.5 获取请求体数据

2.5.1 准备工作

​ 在子应用home中新增视图函数index2及建立路由映射关系

  • 视图函数

    def index3(request):
        """ 获取请求体数据 """
    	# request相关方法代码
        return HttpResponse('OK')
    
  • 路由映射关系

        path('index3/', views.index3),
    
  • 由于只有PUT/DELETE/PATCH请求方式拥有请求体,所以提前准备好Postman

2.5.2 获取请求体数据的方法介绍
  • request.POST:接收客户端html表单数据(postman设置了发送请求通过form-data发送),这种方法不能接收上传文件
  • request.body:接收Json格式数据,其实是拿到原生的请求体数据,从http协议中提取出来没有经过任何处理的原生数据
    • 原生请求体样式我们是无法直接使用的,如果是知道是json样式,可以采用下面的这种方式处理:
      • import json
      • json.loads(request.body)
    • 通过上述这种方式得确保是json格式,其他样式解析出来的数据依旧不能使用,甚至会报错

2.6 获取请求头数据

2.6.1 准备工作
def index4(request):
    """ 获取请求头数据 """
    return HttpResponse('OK')
    path('index4/', views.index4),
2.6.2 获取请求头数据的方法介绍
  • request.META:获取原生请求头数据

2.7 获取上传文件

2.7.1 获取上传文件的方法介绍
  • request.FILES:接收所有的上传文件
  • request.FILES.get(key):接收单个文件上传处理对象,获取到的参数类型是InMemoryUploadFile

三、响应Response

3.1 视图响应数据

​ django和大多数的web框架一样,针对http的响应,提供了两种不同的响应方式:

  • 响应内容,就是直接返回数据给客户端
    • 响应html内容(一般用于web前后端不分离的项目)
    • 响应json内容(一般用于开发web前后端分离的项目的api接口开发)
  • 响应页面,就是通过返回页面跳转的信息给浏览器,让浏览器自己进行页面跳转
3.1.1 返回HTML数据

​ HttpResponse可以直接返回html内容

def index5(request):
    """ 响应html内容 """
    return HttpResponse(content='<H1>OK</H1>', status=201)
3.1.2 返回Json

方式一:通过导入json包响应

import json

def index6(request):
    """ 响应json内容 """
    data = {
        'name': 'Abo',
        'age': 22,
        'sex': '男'
    }
    res = json.dumps(data)
    return HttpResponse(content=res, content_type='application/json')

​ 返回json数据,可以通过HttpRequestd的属性:content_type来指定数据的返回格式

  • content_type的默认值是text/html
  • 如果指定返回格式为json,可以指定为:content_type='application/json'

方式二:通过导入JsonResponse响应

from django.http.response import JsonResponse


def index7(request):
    """ 响应json内容 """
    data = {
        'name': 'Abo',
        'age': 22,
        'sex': '男'
    }

    return JsonResponse(data=data)
说明:
  • JsonResponse继承自HttpResponse,是专门用于响应Json数据的类
  • 使用JsonResponse响应时不再是使用content指定响应的数据,而是通过data来指定响应的数据
  • 使用JsonResponse响应时不再需要指定content_type了,其内部已经指定了content_type='application/json‘
3.1.3 返回图片信息
def index7(request):
    """ 响应纯图片信息内容 """
    content = open('release.png', 'rb').read()

    return JsonResponse(content, content_type='image/jpeg')
3.1.4 提供下载支持
def index7(request):
    """ 提供下载支持(以zip格式演示,可以是其他格式) """
    with open('./basic-2.2.1.zip', 'rb') as f:
        content = f.read()

    return JsonResponse(content, content_type='application/x-zip-compressed')
3.1.5 自定义响应头
def index7(request):
    """ 自定义响应头 """
	response = HttpResponse('ok')
	reponse['company'] = 'AboCompany'  # 给响应对象设置自定义响应头
    
    return response
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值