tags:

views:

105

answers:

5

I need to return css files and js files according to specific logic. Clearly, static serve does not perform what I need. I have a view, whose render method uses logic to find the proper file, but then I have to return it. Technically, I can just read the file and stuff it into a HttpResponse object with the proper mime type, but I was wondering if there was a better strategy. (like fpassthru() in php)

A: 

It should be wasteful to use django to serve static content (not to mention, several orders of magnitude slower).

I'd rather convert the view into a context processor and use the variables in templates to find what blocks to include.

Lakshman Prasad
that's exactly what I want to move away from. I am already including the stuff, with the result that the css and js files are included hardcoded into the html file, preventing any form of caching (since the page as a whole is deemed to change). I want to be able to ship js and css, but since this shipment is dependent on the plugins of my application that are available, I need to perform some logic before shipping the file.
Stefano Borini
Tom
A: 

Pass an iterator (such as the result of open()) to the HttpResponse constructor.

Ignacio Vazquez-Abrams
A: 

Why not return an HttpResponseRedirect to the location of the correct static file?

Daniel Roseman
because the file is not directly accessible.
Stefano Borini
+2  A: 

What webserver software are you using?

At least for Apache and NginX, there is a module enabling you to use the X-SendFile HTTP header. The NginX website says Lighty can do this, too.

In your wrapper view:

...

abspath = '/most_secret_directory_on_the_whole_filesystem/protected_filename.css'

response = HttpResponse()
response['X-Sendfile'] = abspath

response['Content-Type'] = 'mimetype/submimetype'
# or let your webserver auto-inject such a header field
# after auto-recognition of mimetype based on filename extension

response['Content-Length'] = <filesize>
# can probably be left out if you don't want to hassle with getting it off disk.
# oh, and:
# if the file is stored via a models.FileField, you just need myfilefield.size

response['Content-Disposition'] = 'attachment; filename=%s.css' \
    % 'whatever_public_filename_you_need_it_to_be'

return response

Then you can connect the view via http://mysite.com/url_path/to/serve_hidden_css_file/.

You can use it anytime you need to do something upon a file being requested that should not be directly accessible to users, like limiting who can access it, or counting requests to it for stats, or whatever.

For Apache: http://tn123.ath.cx/mod_xsendfile/
For NginX: http://wiki.nginx.org/NginxXSendfile

A: 

This is what I used:

    abspath = open('/home/poop/serve/test.pdf','r')
    response = HttpResponse(content=abspath.read())
    response['Content-Type']= 'application/pdf'
    response['Content-Disposition'] = 'attachment; filename=%s.pdf' \
                                       % 'whatever'
    return response
Uku Loskit