Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I get the content length of a Django response object?

In Django, I try to logging the request and response content length, which exactly the same as what Django server prints to stderr.

[05/Apr/2011 22:59:08] "GET /pages/ HTTP/1.1" 200 332161
[05/Apr/2011 22:59:15] "GET /pages/12 HTTP/1.1" 301 0
[05/Apr/2011 22:59:15] "GET /pages/12/ HTTP/1.1" 200 361474
[05/Apr/2011 22:59:16] "GET /pages/12/load/tags/ HTTP/1.1" 200 13899
[05/Apr/2011 22:59:16] "GET /pages/12/load/comments/ HTTP/1.1" 200 82

So, I write a simple middleware as follows, but, the value of 'Content-Length' is always empty.

class LogHttpResponse(object):
    def process_response(self, request, response):
        import datetime  
        print response.items()
        time_text = datetime.datetime.now().strftime('%m/%d/%Y %H:%M:%S')
        print '[%s] "%s %s" %d %s' % (time_text, request.method, request.path, 
                                      response.status_code, 
                                      response.get('Content-Length', ''))
        return response 

I've checked through fire-debug, there is 'Content-Length' in the response headers. But there is no 'Content-Length' in the middleware, "print response.items()" shows:

[('Content-Type', 'text/html; charset=utf-8')]

Is there any problem of the middleware orders?

like image 602
William Avatar asked Apr 05 '11 16:04

William


People also ask

What is HttpResponse in Django?

HttpResponse (source code) provides an inbound HTTP request to a Django web application with a text response. This class is most frequently used as a return object from a Django view.

What is request method == POST in Django?

method == "POST" is a boolean value - True if the current request from a user was performed using the HTTP "POST" method, of False otherwise (usually that means HTTP "GET", but there are also other methods).

How are requests and responses processed in Django?

Django uses request and response objects to pass state through the system. When a page is requested, Django creates an HttpRequest object that contains metadata about the request. Then Django loads the appropriate view, passing the HttpRequest as the first argument to the view function.

What is the typical order of an HttpRequest response cycle in Django?

Layers of Django Application Django request middlewares follows the order while processing the request. Suppose if we have request middlewares in the order A, B, C then the request first processed by the middleware A and then B and then C. Django comes up with bunch of default middlewares.


2 Answers

I've checked through fire-debug, there is 'Content-Length' in the response headers. But there is no 'Content-Length' in the middleware [...] Is there any problem of the middleware orders?

Yes. Middleware classes are applied from top-down (in settings.MIDDLEWARE_CLASSES) when processing request and bottom-up when processing the response. If you have 'django.middleware.http.ConditionalGetMiddleware' in you middleware classes it will add a 'Content-Length' header to the HttpResponse.

Though if you put your middleware class after 'django.middleware.http.ConditionalGetMiddleware' in settings.MIDDLEWARE_CLASSES it will apply this one first when processing the response and then apply the ConditionalMiddleware afterwards. That's why you see a Content-Length header in Firebug, though its not yet processed when you Middleware is called.

See Django Middleware documentation for more information about Middleware's.

like image 186
Torsten Engelbrecht Avatar answered Sep 19 '22 19:09

Torsten Engelbrecht


How about len(response.content)? That’d give you the number of characters in the response’s content. I guess that isn’t necessarily the same as the number of bytes.

like image 30
Paul D. Waite Avatar answered Sep 20 '22 19:09

Paul D. Waite