[Answered ]-Can I access the request object in a console error?

1👍

I ended up using the pip package django-middleware-global-request. I can import this anywhere and use the request object its method get_request.

from django_middleware_global_request.middleware import get_request


class JsonFormatter(handler.FluentRecordFormatter):

  def format(self, record):
    def add_request_data(data):
    request = get_request()
    if request:
      # do stuff with request and data
    return data

0👍

If you want to debug the error use breakpoint(), this way you will get an interactive console where you can type in the variable and see its value.

If you want to log the request object modify your JsonFormatter like this

class JsonFormatter(handler.FluentRecordFormatter):

    def format(self, record):

        if type(record) in [str]:
            data = super(JsonFormatter, self).format(record)

        else:
            # request object | manually serialize it
            request_data = f"{request.status} | {request.user.username} | {request.data} | ... other request data"
            data = super(JsonFormatter, self).format(request_data)

        return json.dumps(data)

Now in your views.py for IndexPage:

class IndexPage():

    def get(self, request, *args, **kwargs):
    
        MODULE_LOGGER.warning(request)
        # code...
        return self.render_to_response(context)

0👍

If you like to know more about logger you need to check Python documentation, it’s not related to Django. Django uses a JSON to configure Python loggers. See https://docs.python.org/3/howto/logging.html

To have request inside each log, you can go the explicit way, i.e. replace all

MODULE_LOGGER.warning("log me!")

with

MODULE_LOGGER.warning("log me!", extra={"request": request})

then inside your formatter you’ll have the request object

class JsonFormatter(handler.FluentRecordFormatter):
    def format(self, record):
        print(record.request) # Probably you want to do something more useful here.
        data = super(JsonFormatter, self).format(record)
        return json.dumps(data)

If this doesn’t suit you and you want to automatically and implicitly pass request to your logger, then you need to do something more complex like a middleware. Most of time Django is deployed using a thread/process based servers, so current thread is handling one request at a time. So we can store current request object in a thread local storage (with a middleware), and pick it up in our logger.

Add this, let say in file "my_pretty_middleware.py"

import threading

_local = threading.local()
_local.current_request = None


class StoreRequestMiddleware:
    def __init__(self, get_response):
        self.get_response = get_response

    def __call__(self, request):
        try:
            _local.current_request = request
            return self.get_response(request)
        finally:
            _local.current_request = None


def get_current_request():
    return _local.current_request

Then add this middleware at top of your middlewares. Like

MIDDLEWARE = [
    "my_pretty_middleware.StoreRequestMiddleware"
    "django.middleware.security.SecurityMiddleware",
    "django.middleware.common.CommonMiddleware",
    ...
]

Then in your formatter (or whatever part of code), you can get the request object.

from my_pretty_middleware import get_current_request


class JsonFormatter(handler.FluentRecordFormatter):
    def format(self, record):
        request = get_current_request()
        if request:  # Beware it can be None in case you're logging outside of request cycle.
            print(request)  # Probably you'd like to do something else
        data = super(JsonFormatter, self).format(record)
        return json.dumps(data)

0👍

check and install requestLogging.

it helps you modify and format your logs with the request object.

👤Chymdy

Leave a comment