Python Django请求和响应对象详解

Django请求和响应对象

Django 使用请求和响应对象在系统中传递状态。

当一个页面被请求时,Django 会创建一个 HttpRequest 对象,这个对象包含了请求的元数据。然后,Django 加载相应的视图,将 HttpRequest 作为视图函数的第一个参数。每个视图负责返回一个 HttpResponse 对象。

HttpRequest对象

下面介绍HttpRequest对象常用的属性和方法。

HttpRequest常用属性

1.HttpRequest.body

原始的 HTTP 请求体作为一个字节字符串。这对于以不同方式处理非常规 HTML 表单的数据很有用:二进制图像,XML 有效负载等。对于处理传统的表单数据,使用 HttpRequest.POST

2.HttpRequest.method

代表请求中使用的 HTTP 方法的字符串,一定是大写字母。

3.HttpRequest.GET

一个类似字典的对象,包含所有给定的 HTTP GET 参数。

4.HttpRequest.POST

一个类似字典的对象,包含所有给定的 HTTP POST 参数,前提是请求包含表单数据。如果你需要访问请求中发布的原始或非表单数据,可以通过 HttpRequest.body 属性来访问。

以上的4个属性是我们最常用的HttpRequest属性。结合实际,我们可能写出的代码如下:

if request.method == "POST":        # POST请求方法
    try:
        data = json.loads(request.body)     # 获取POST请求携带的非表单数据(JSON数据)
    except json.JSONDecodeError:
        return JsonResponse({"status": "1", "msg": "数据格式错误"})
    # 表单数据
    # keys = request.POST.get("keys")       # 如果POST携带的是表单数据,可以这样获取。
elif request.method == "GET":
    keys = request.GET.get("keys")      # 获取get请求携带的参数
    return JsonResponse({"status": "0", "msg": "请求成功"})
else:
    return JsonResponse({"status": "0", "msg": "请求方法错误"})

5.HttpRequest.COOKIES

一个包含所有 cookies 的字典。键和值是字符串。

6.HttpRequest.FILES

一个类似字典的对象,包含所有上传的文件。FILES 中的每个键是 中的 name。FILES 中的每个值是一个 UploadedFile。

FILES 只有在请求方法是 POST,并且发布请求的

有 enctype=“multipart/form-data” 的情况下,才会包含数据。否则,FILES 将是一个类似字典的空白对象。

7.HttpRequest.META

一个包含所有可用的 HTTP 头文件的字典。可用的头信息取决于客户端和服务器。一些可能的例子如下:

1.CONTENT_LENGTH —— 请求体的长度(字符串)。

2.CONTENT_TYPE —— 请求体的 MIME 类型。

3.HTTP_ACCEPT —— 可接受的响应内容类型。

4.HTTP_ACCEPT_ENCODING —— 可接受的响应编码。

5.HTTP_ACCEPT_LANGUAGE —— 可接受的响应语言。

6.HTTP_HOST —— 客户端发送的 HTTP 主机头。

7.HTTP_REFERER —— referrer 页面,如果有的话。

8.HTTP_USER_AGENT —— 客户端的用户代理字符串。

9.QUERY_STRING —— 查询字符串,是一个单一的(未解析的)字符串。

10.REMOTE_ADDR —— 客户机的 IP 地址。

11.REMOTE_HOST —— 客户机的主机名。

12.REMOTE_USER —— Web 服务器认证的用户,如果有的话。

13.REQUEST_METHOD —— “GET” 或 “POST” 等字符串。

14.SERVER_NAME —— 服务器的主机名。

15.SERVER_PORT —— 服务器的端口(字符串)。

请求中的任何 HTTP 头都会被转换为 META 键,方法是将所有字符转换为大写字母,用下划线代替任何连字符,并在名称前加上 HTTP_` 前缀。例如,请求头里的X-CSRFToken在META中变为HTTP_X_CSRFTOKEN.

中间件设置的属性

Django 的 contrib 应用中包含的一些中间件会在请求中设置属性。

1.HttpRequest.session

来自 SessionMiddleware。一个可读可写的,类似字典的对象,代表当前会话。

2.HttpRequest.user

从 AuthenticationMiddleware。AUTH_USER_MODEL 的一个实例,代表当前登录的用户。如果用户当前没有登录,user 将被设置为一个 AnonymousUser 的实例。你可以用 is_authenticated 来区分它们,例如:

if request.user.is_authenticated:
    ... # Do something for logged-in users.
else:
    ... # Do something for anonymous users.

如果使用Nginx+uWsgi的方式部署Django项目,那么META中的REMOTE_ADDR,REMOTE_HOST等不正确的,因为通过Nginx代理转发到uWsgi监听的端口,这时候应用程序获取的客户端信息就是127.0.0.1的本机信息,而不是真实客户端的信息。因此,需要在Nginx中添加如下参数:

uwsgi_param  Host $host;
uwsgi_param  X-Real-IP $remote_addr;
uwsgi_param  X-Forwarded-For $proxy_add_x_forwarded_for;
uwsgi_param  X-Forwarded-Proto $http_x_forwarded_proto;

至于你需要的到底是X-Real-IP还是X-Forwarded-For,取决于你的业务逻辑。

QueryDict对象

在一个 HttpRequest 对象中, GET 和 POST 属性是 django.http.QueryDict 的实例,这是一个类似字典的类,用来处理同一个键的多个值。这是很有必要的,因为一些 HTML 表单元素,尤其是