request 简述
- 服务器接收到http协议的请求后,会根据报文创建HttpRequest对象。
- 在django中,视图函数定义的第一个参数总是 request ,如
def request_get_post(request)
,该参数request简称为请求,是来自HttpRequest对象在django.http模块中定义的HttpRequest对象的API。
- request 属性
属性 |
简介 |
类型 |
request.body |
原始请求主体内容 |
bytes |
request.path |
不包含域名的完整访问路径 |
str |
request.method |
HTTP访问的方法,其中字母必定全是大写。常见有 GET、POST |
str |
request.encoding |
提交的数据的编码格式 |
str |
request.content_type |
从 header 中解析出的文件类型 |
str |
request.content_params |
包含在 header 中的参数 |
dict |
request.COOKIES |
包含所有cookies的字典 |
dict |
request.FILES |
包含上传的文件 |
MultiValueDict |
request.GET |
GET请求的参数 |
QueryDict |
request.POST |
获取POST方式提交的数据 |
QueryDict |
方法 |
简介 |
request.get_full_path() |
返回完整访问路径,包含路径中携带的参数 |
request.is_secure |
判断是否为 https 请求 |
request.is_ajax() |
判断是否为 ajax 请求 |
- 更多介绍可以查看官方文档 https://docs.djangoproject.com/zh-hans/2.1/ref/request-response/
request 的 GET 和 POST
- QueryDict,在一个HttpRequest对象中,GET和POST属性都是django.http.QueryDict的实例,这些实例的类字典类型是为了解决诸如 使用一键多值传输的元素定制的获取值的办法。
- 使用一个打钩选值的前端模板来测试
<form action="" method="post"> {% csrf_token %}
<input type="checkbox" name="test" value="测试1"> 测试1
<input type="checkbox" name="test" value="测试2"> 测试2
<input type="checkbox" name="test" value="测试3"> 测试3
<input type="submit">
</form>
- GET 与 POST 的判断与变更页面的示例
- 使用request属性中提到的method来判断
- 当使用GET请求时,返回页面
- 当使用POST请求时,返回一个POST成功提示
def request_get_post(request):
if request.method == 'GET':
return render(request, 'request/request.html')
if request.method == 'POST':
return HttpResponse('访问成功')
- 从页面取值
QueryDict有两个取值的方法 get() 和 getlist();get() 通过键来获取值,只能获取键的一个值,如果键有多个值,则取到最后一个;getlist() 通过键来获取值,可以获取键的所有值并以列表的形式返回。修改 request_get_psot() 代码,print 打印出 GET 和 POST 取到的值。
- GET 取值
- request.GET.get()
- request.GET.getlist()
- POST 取值
- request.POST.get()
- request.POST.getlist()
def request_get_post(request):
if request.method == 'GET':
value = request.GET.get('value')
values = request.GET.getlist('value')
print(value)
print(values)
return render(request, 'request/request.html')
elif request.method == 'POST':
value = request.POST.get('test')
values = request.POST.getlist('test')
print(value)
print(values)
return HttpResponse('访问成功')
http://172.16.8.128:8000/request/req/?value=abc&value=ova
ova
['abc', 'ova']
- POST访问的方法与取到的值
测试2
['测试1', '测试2']
类视图
在这之前,用的视图均由函数创建,称为函数视图,函数视图十分便捷,且易于理解。但是在增加了对GET和POST的不同响应后,代码便不那么易读且复用性不高。为了应对各种各样的请求方法,引入类视图来解决。
- 类视图来自于 django.views.generic.base.View,所有的其他基于类的视图都从该基类继承,但严格来说,该类并不是一个通用视图,因此可以从 django.views 来导入。
- 改写上部分代码示例:
from django.shortcuts import render
from django.http import HttpResponse
from django.views import View
class RequestGP(View):
def get(self, request):
value = request.GET.get('value')
values = request.GET.getlist('value')
print(value)
print(values)
return render(request, 'request/request.html')
def post(self, request):
value = request.POST.get('test')
values = request.POST.getlist('test')
print(value)
print(values)
return HttpResponse('访问成功')
- url 映射方法 as_view()
类视图不能使用视图函数的映射方法,而应该使用继承于 View 的 as_view(),配置如下
path('req/', RequestGP.as_view())
['get', 'post', 'put', 'patch', 'delete', 'head', 'options', 'trace']
文件上传 InMemoryUploadedFile
- 从 request.FILES 中可以取得上传的文件
- 上传的文件为 django.core.files.uploadedfile.InMemoryUploadedFile 类型,以下称"UploadFile"。
- UploadFile 中含有以下属性和方法,这里主要用到 name 属性和 chunks() 方法
[‘charset’, ‘chunks’, ‘close’, ‘closed’, ‘content_type’, ‘content_type_extra’, ‘encoding’, ‘field_name’, ‘file’, ‘fileno’, ‘flush’, ‘isatty’, ‘multiple_chunks’, ‘name’, ‘newlines’, ‘open’, ‘read’, ‘readable’, ‘readinto’, ‘readline’, ‘readlines’, ‘seek’, ‘seekable’, ‘size’, ‘tell’, ‘truncate’, ‘writable’, ‘write’, ‘writelines’]
- UploadFile.name:文件名
- UploadFile.chunks() :以块为单位进行分片读取
文件上传示例
- 创建文件存储目录 media
- 在 settings.py 中设置存储路径
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
- 创建用于上传的 form 表单
<form action="" method="post" enctype="multipart/form-data">
{% csrf_token %}
<input type="file" name="upload">
<input type="submit">
</form>
- 创建类视图
from django.shortcuts import render
from django.http import HttpResponse
from django.views import View
from mydjango.settings import MEDIA_ROOT
import os
import uuid
class Upload(View):
def get(self, request):
return render(request, 'request/upload.html')
def post(self, request):
file = request.FILES.get('upload')
path_name = self.named(file.name)
with open('{}'.format(path_name), 'wb') as f:
for chunk in file.chunks():
f.write(chunk)
return HttpResponse('上传完成')
def named(self, filename):
"""
输入一个原文件名
生成包含文件存储路径的文件名
:return: a string
"""
ext = os.path.splitext(filename)[1]
return os.path.join(MEDIA_ROOT, str(uuid.uuid4()) + ext)
- 配置路由映射
path('upload/', Upload.as_view(), name='upload')
END
参考文献