Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Serialize Django Request

I'd like to serialize the Django request in order to log it in a DB. I tried different approaches but none of them successfully.

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

But this raise the error

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

Probably because I'm using the rest-framework as a Middleware. I also used

srd = json.dumps(request)

In this case the error is

Object of type 'WSGIRequest' is not JSON serializable

Any ideas how to fix this?

like image 802
Fucio Avatar asked Jul 27 '26 20:07

Fucio


1 Answers

I've faced similar problem when trying to store received requests META data in JSONField. Problem is that request.META is a dict but it's not appropriate JSON.

Example request.META I have is:

{
   "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"
...
}

So as you can see first few keys with wsgi prefix is inappropriate JSON format what you can also check online at: http://json.parser.online.fr/

So to store request.META as JSON dict it's necessary to get rid of this keys. The trick is that you cannot use request.META.pop("wsgi.version") because request.META is not appropriate JSON format :)

What I did is I've created helper function:

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"],
    }

and use it like:

meta_data_as_json = create_request_meta_json_object(request.META)
like image 92
Michael Stachura Avatar answered Jul 30 '26 05:07

Michael Stachura