Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Django slow performance on processing requests

I have a django platform and I've found a strange slow performance when the server tries to response some http requests.

I've managed to isolate a little useless code that shows a strange delay, from which all the others can be derived.

case 1) If I have this function:

def get_n_events(request):
    a = request.user
    return HttpResponse("5")

the response is very fast, as expected: enter image description here

Only 12.61ms, very fast, as expected.

case 2) But if I have this function:

def get_n_events(request):
    a = request.user.username
    return HttpResponse("5")

the response: enter image description here

it takes more than 2 seconds!

How can be this delay explained and how can I avoid this huge time when I need to access the data inside the request? (For example, in my case I need to know the request.user.group_name, but it takes too much tome to get a response.

UPDATE

I made some tests with Django Debug Toolbar and I saw that the huge time is not due to SQL runtime. enter image description here

As we can see, the SQL takes only 183ms, but the request has 1354msecs. Where does this time come from and how can I reduce it?

like image 862
Sergio Ferrer Sánchez Avatar asked Oct 17 '25 08:10

Sergio Ferrer Sánchez


1 Answers

request.user is a lazy object, so as long as you do not ask for an attribute, or call str(..), etc. over it, no database query is made.

Indeed, if we take a look at the AuthenticationMiddleware [GitHub], we see:

class AuthenticationMiddleware(MiddlewareMixin):
    def process_request(self, request):
        assert hasattr(request, 'session'), (
            "The Django authentication middleware requires session middleware "
            "to be installed. Edit your MIDDLEWARE setting to insert "
            "'django.contrib.sessions.middleware.SessionMiddleware' before "
            "'django.contrib.auth.middleware.AuthenticationMiddleware'."
        )
        request.user = SimpleLazyObject(lambda: get_user(request))

So request.user presents itself as if it was loaded, but as long as you do not need an attribute, etc. from it, it is just a proxy object that promises to make a query if necessary.

like image 79
Willem Van Onsem Avatar answered Oct 20 '25 20:10

Willem Van Onsem



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!