Feature request: serve_file() view in static app

156 views
Skip to first unread message

Rivo Laks

unread,
Jan 13, 2014, 3:39:31 PM1/13/14
to django-d...@googlegroups.com
Hi everyone,

I'm proposing to split out from the django.views.static.serve() view the functionality to serve a single static file.
The new view could be named serve_file(), would take request and fullpath as parameters and would serve the given file. The code would essentially be the second half of the current serve() view.
The serve() view could then be modified to use serve_file(), once the fullpath has been found and isdir() check is done.

My usecase:
I'm writing a single-page javascript app, using Django for backend logic and API. The client side consists of js/css assets and a single html file. I want that html file to be served by the Django app whenever a user makes a request to a url that doesn't match anything else (e.g. api urls). The javascript app does its own url routing, so if the user comes to  /foo/bar  , the same html file is served and the javascript shows the right page to the user.
ATM I've created a fallback view that contains copy-paste code from serve() and has the fullpath variable hardcoded. The reason I like serve() is that it contains some useful logic, such as being able to respond with 304 (Not Modified) and setting some useful http headers.

I can take care of creating a patch if the idea sounds good.

Rivo

Marc Tamlyn

unread,
Jan 13, 2014, 3:49:33 PM1/13/14
to django-d...@googlegroups.com
`django.views.static.serve` is, in the words of the documentation, grossly inefficient and probably insecure, so it is unsuitable for production. Any attempt to make it more useful than its current use case (serving staticfiles in development) is unlikely to happen.

Marc


--
You received this message because you are subscribed to the Google Groups "Django developers" group.
To unsubscribe from this group and stop receiving emails from it, send an email to django-develop...@googlegroups.com.
To post to this group, send email to django-d...@googlegroups.com.
Visit this group at http://groups.google.com/group/django-developers.
To view this discussion on the web visit https://groups.google.com/d/msgid/django-developers/5d9f0449-2b46-4c50-81f5-3b2e43e16512%40googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.

Rivo Laks

unread,
Jan 14, 2014, 3:18:29 PM1/14/14
to django-d...@googlegroups.com
Hm, indeed.

Is there any better alternative or best practice for my usecase though? Basically I want a view that responds with contents of a static file and django.views.static.serve() does pretty much exactly that. Or is my usecase just too fringe to be handled by Django core?

Rivo

Aymeric Augustin

unread,
Jan 14, 2014, 4:02:43 PM1/14/14
to django-d...@googlegroups.com
You don’t need an application server running Django to serve a file. A plain and simple web server such as Apache or nginx will do.

It’s a good practice to put application servers behind a web server acting as a reverse proxy (and possibly load balancer), so you probably have one already.

It’s possible to serve the same page on any URL, it’s just a matter of writing the appropriate configuration for the server you’re using.

I hope this helps!

-- 
Aymeric.



Rivo Laks

unread,
Jan 14, 2014, 4:52:26 PM1/14/14
to django-d...@googlegroups.com
Nono, I need Django for the API and backend logic :-)

Let me illustrate my needs a bit better:
- I have Django instance that serves API and a few related services and handles backend logic.
- I also have nginx server in front of the Django instance, that also serves static files (css/js, which are always under /assets/ url prefix).
- There are some url prefixes such as /api/* that have to be handled by the Django app.
- All the other urls should be responded to with my static index.html file. Almost like a 404 handler that responds with static file.

I suppose I could add all the prefixes that should be handled by the Django app into nginx config. Matching requests would then be forwarded to the Django app and all others would be handled by nginx.
But I'd rather not do that, since then I'd have to also keep the nginx config in sync when I add another prefix to be handled by Django.
The number of prefixes probably wouldn't hit double digits, so maybe it is the way to go, but I'm still wondering if there's a good way to handle it inside Django.

Rivo

Marc Tamlyn

unread,
Jan 14, 2014, 4:58:13 PM1/14/14
to django-d...@googlegroups.com
If you're on nginx, There are also some cases where you may find X-ACCEL-REDIRECT useful, which allows you to return a blank HTTPResponse from Django and tell nginx to serve a file.


In any case, this is now more suited to a Django-users discussion. If you ask there, I'm sure there may be other possible solutions people know of.

Thanks,
Marc


Rivo Laks

unread,
Jan 14, 2014, 5:38:45 PM1/14/14
to django-d...@googlegroups.com
X-accel looks promising, I'll see if it can solve my problem. Thanks!

Rivo

Apostolos Bessas

unread,
Jan 15, 2014, 2:52:08 AM1/15/14
to django-d...@googlegroups.com
Hi Rivo,

So, if I understand this correctly, you need Django to figure out,
whether you need to serve the static HTML page or not.

In this case, you could use http://wiki.nginx.org/X-accel; that is,
return a HttpResponse with the X-Accel-Redirect header pointing to the
static file.

I suppose this is the most efficient way to serve static files only
when certain conditions are met (e.g. you need a permission check
first), without using Django to actually send the file.

I hope this helps.

Apostolis
> https://groups.google.com/d/msgid/django-developers/c15fefc6-a46b-493b-8f3a-f92b16ffdfcf%40googlegroups.com.

Andre Terra

unread,
Jan 15, 2014, 9:04:59 AM1/15/14
to django-d...@googlegroups.com

German Larrain

unread,
Jan 19, 2014, 8:36:21 AM1/19/14
to django-d...@googlegroups.com
PyPI packages 'static' and 'dj-static' might help you.
Reply all
Reply to author
Forward
0 new messages