From Django’s context: Middleware is a framework of hooks into Django’s request/response processing. It’s a light, low-level “plugin” system for globally altering Django’s input or output. Middleware is like a layer which processes every request and response. Instead of logging requests and responses in resp. views, its better to do at middleware layer which will log every incoming request. Why better? it will log unhandled requests/views one time job, no need to configure for every request/view Here, we are using Django’s middleware semantics to construct a middleware which will log all requests and corresponding responses. Create a middleware file Create a middleware folder in your project directory. mkdir middleware touch middleware/__init__.py Create a RequestLogMiddleware class in /middleware/request_log.py, see below: """ Middleware to log `*/api/*` requests and responses. """ import socket import time import json import logging request_logger = logging.getLogger(__name__) class RequestLogMiddleware: """Request Logging Middleware.""" def __init__(self, get_response): self.get_response = get_response def __call__(self, request): start_time = time.time() log_data = { "remote_address": request.META["REMOTE_ADDR"], "server_hostname": socket.gethostname(), "request_method": request.method, "request_path": request.get_full_path(), } # Only logging "*/api/*" patterns if "/api/" in str(request.get_full_path()): req_body = json.loads(request.body.decode("utf-8")) if request.body else {} log_data["request_body"] = req_body # request passes on to controller response = self.get_response(request) # add runtime to our log_data if response and response["content-type"] == "application/json": response_body = json.loads(response.content.decode("utf-8")) log_data["response_body"] = response_body log_data["run_time"] = time.time() - start_time request_logger.info(msg=log_data) return response # Log unhandled exceptions as well def process_exception(self, request, exception): try: raise exception except Exception as e: request_logger.exception("Unhandled Exception: " + str(e)) return exception Django allows us to write pre and post api-processing logic via __call__ method. Here we are logging only requests with /api/ in its path. Activate the middleware Activate the middleware by adding its path in MIDDLEWARE list in your Django’s application settings.py (below: last value is added to the middleware list): MIDDLEWARE = [ ... "django.contrib.messages.middleware.MessageMiddleware", # Request Logger ".middleware.request_log.RequestLogMiddleware", ] Replace with your application name.