【问题标题】:Serialize Django Request序列化 Django 请求
【发布时间】:2019-05-06 20:25:43
【问题描述】:

我想序列化 Django 请求以便将其记录到数据库中。我尝试了不同的方法,但都没有成功。

class RunTest(View):
  def get(self, request, url):
     srd = serializers.serialize('json', request)
     return HttpResponse(json.dumps(request.META))

但这会引发错误

module 'rest_framework.serializers' has no attribute 'serialize'

可能是因为我将 rest-framework 用作中间件。 我也用过

srd = json.dumps(request)

在这种情况下,错误是

Object of type 'WSGIRequest' is not JSON serializable

有什么想法吗?非常感谢

【问题讨论】:

  • 你想用它做什么? vars(request) 可能吗?
  • 我想将它保存在数据库中,因为我想构建一个记录所有请求和响应的代理
  • 将这些数据保存到数据库后,您想做什么?没有?你会用它吗?
  • 从 django.core 导入序列化器
  • 只显示给用户

标签: django django-rest-framework serialization


【解决方案1】:

在尝试将收到的请求 META 数据存储在 JSONField 中时,我遇到了类似的问题。问题是 request.META 是一个字典,但它不适合 JSON。

我拥有的示例 request.META 是:

{
   "wsgi.version": (1, 0), 
   "wsgi.url_scheme": "http", 
   "wsgi.input": <_io.BufferedReader name=10>, 
   "wsgi.errors": <_io.TextIOWrapper name="<stderr>" mode="w" encoding="utf-8">,
   "wsgi.multithread": True, 
   "wsgi.multiprocess": False, 
   "wsgi.run_once": False, 
   "SERVER_SOFTWARE": "Werkzeug/1.0.1", 
   "REQUEST_METHOD": "POST", 
   "SCRIPT_NAME": "", 
   "PATH_INFO": "/api/v1/vouchers/voucher-distribute/", 
   "QUERY_STRING": "", 
   "REQUEST_URI": "/api/v1/vouchers/voucher-distribute"
...
}

因此,您可以看到带有 wsgi 前缀的前几个键是不合适的 JSON 格式,您也可以在线查看:http://json.parser.online.fr/

所以要将 request.META 存储为 JSON 字典,有必要摆脱这些键。诀窍是你不能使用 request.META.pop("wsgi.version") 因为 request.META 不是合适的 JSON 格式:)

我所做的是创建了辅助函数:

def create_request_meta_json_object(meta_data):
    return {
        "REQUEST_METHOD": meta_data["REQUEST_METHOD"],
        "SERVER_SOFTWARE": meta_data["SERVER_SOFTWARE"],
        "REQUEST_METHOD": meta_data["REQUEST_METHOD"],
        "SCRIPT_NAME": meta_data["SCRIPT_NAME"],
        "PATH_INFO": meta_data["PATH_INFO"],
        "QUERY_STRING": meta_data["QUERY_STRING"],
        "REQUEST_URI": meta_data["REQUEST_URI"],
        "RAW_URI": meta_data["RAW_URI"],
        "REMOTE_ADDR": meta_data["REMOTE_ADDR"],
        "REMOTE_PORT": meta_data["REMOTE_PORT"],
        "SERVER_NAME": meta_data["SERVER_NAME"],
        "SERVER_PORT": meta_data["SERVER_PORT"],
        "SERVER_PROTOCOL": meta_data["SERVER_PROTOCOL"],
        "HTTP_X_FORWARDED_HOST": meta_data["HTTP_X_FORWARDED_HOST"],
        "HTTP_X_FORWARDED_PORT": meta_data["HTTP_X_FORWARDED_PORT"],
        "HTTP_ACCEPT_ENCODING": meta_data["HTTP_ACCEPT_ENCODING"],
        "HTTP_USER_AGENT": meta_data["HTTP_USER_AGENT"],
        "HTTP_FROM": meta_data["HTTP_FROM"],
        "HTTP_ACCEPT": meta_data["HTTP_ACCEPT"],
        "CONTENT_TYPE": meta_data["CONTENT_TYPE"],
        "CONTENT_LENGTH": meta_data["CONTENT_LENGTH"],
        "HTTP_CONNECTION": meta_data["HTTP_CONNECTION"],
        "HTTP_X_NGINX_PROXY": meta_data["HTTP_X_NGINX_PROXY"],
        "HTTP_X_FORWARDED_PROTO": meta_data["HTTP_X_FORWARDED_PROTO"],
        "HTTP_X_FORWARDED_FOR": meta_data["HTTP_X_FORWARDED_FOR"],
        "HTTP_X_REAL_IP": meta_data["HTTP_X_REAL_IP"],
    }

并像这样使用它:

meta_data_as_json = create_request_meta_json_object(request.META)

【讨论】:

  • 字典理解怎么样:
【解决方案2】:

您不能序列化 request - 您可以在 DRF 中序列化 request.GET 也称为 request.query_params

srd = json.dumps(request.query_params)

srd = json.dumps(request.GET)

要使用序列化程序,您首先必须创建一个。 Declaring Serializers 是一个很好的起点。

另一个潜在的解决方案是使用字典理解:

meta_keys = {
   "wsgi.version": (1, 0), 
   "wsgi.version": "http", 
   "wsgi.input": object(), 
   "wsgi.errors": object(),
   "wsgi.multithread": True, 
   "wsgi.multiprocess": False, 
   "wsgi.run_once": False, 
   "SERVER_SOFTWARE": "Werkzeug/1.0.1", 
   "REQUEST_METHOD": "POST", 
   "SCRIPT_NAME": "", 
   "PATH_INFO": "/api/v1/vouchers/voucher-distribute/", 
   "QUERY_STRING": "", 
   "REQUEST_URI": "/api/v1/vouchers/voucher-distribute"
}

excluded_meta_keys = ['wsgi.version', 'wsgi.version', 'wsgi.input', 'wsgi.multithread', 'wsgi.multiprocess', 'wsgi.run_once', 'wsgi.errors']

print({key: value for key, value in meta_keys.items() if key not in excluded_meta_keys})

print({key: value for key, value in meta_keys.items() if isinstance(value, (str, bool, int, float))})

结果:

{'SERVER_SOFTWARE': 'Werkzeug/1.0.1', 'REQUEST_METHOD': 'POST', 'SCRIPT_NAME': '', 'PATH_INFO': '/api/v1/vouchers/voucher-distribute/', 'QUERY_STRING': '', 'REQUEST_URI': '/api/v1/vouchers/voucher-distribute'}

{'wsgi.version': 'http', 'wsgi.multithread': True, 'wsgi.multiprocess': False, 'wsgi.run_once': False, 'SERVER_SOFTWARE': 'Werkzeug/1.0.1', 'REQUEST_METHOD': 'POST', 'SCRIPT_NAME': '', 'PATH_INFO': '/api/v1/vouchers/voucher-distribute/', 'QUERY_STRING': '', 'REQUEST_URI': '/api/v1/vouchers/voucher-distribute'}

分别

【讨论】:

  • request.META 呢?
  • request.META 怎么样?你有什么问题?
猜你喜欢
  • 2015-11-10
  • 2015-09-10
  • 1970-01-01
  • 2018-10-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多