视图基础
一、函数视图二、请求
2.1 限制http请求2.2 设置路由绑定视图2.3 视图接收http请求
2.3.1 request对象 2.4 获取查询字符串的参数
2.4.1 准备工作2.4.2 获取查询字符串的方法介绍2.4.3 QueryDict参数集 2.5 获取请求体数据
2.5.1 准备工作2.5.2 获取请求体数据的方法介绍 2.6 获取请求头数据
2.6.1 准备工作2.6.2 获取请求头数据的方法介绍 2.7 获取上传文件
2.7.1 获取上传文件的方法介绍 三、响应Response
3.1 视图响应数据
3.1.1 返回HTML数据3.1.2 返回Json3.1.3 返回图片信息3.1.4 提供下载支持3.1.5 自定义响应头
视图基础 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说明:
QueryDict是参数集对象,类的位置:django.http.QueryDictQueryDict对象继承自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 jsonjson.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='OK', 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



