#119 closed enhancement (wontfix)
Serving media
Reported by: | Owned by: | Adrian Holovaty | |
---|---|---|---|
Component: | Core (Other) | Version: | |
Severity: | normal | Keywords: | media wsgi images |
Cc: | Triage Stage: | Unreviewed | |
Has patch: | no | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | no |
Easy pickings: | no | UI/UX: | no |
Description
There is currently no way of serving media through Django, which might be alright for mod_python as it's counting on Apache, but the WSGI server doesn't have such benefits.
Change History (15)
comment:1 by , 19 years ago
Resolution: | → wontfix |
---|---|
Status: | new → closed |
comment:2 by , 19 years ago
Resolution: | wontfix |
---|---|
Status: | closed → reopened |
I think we should document that mod_python trick we used to use (still use?) where you tun off mod_python handling for a certain path - /m/ for example - to allow media to be served from the corresponding location on the file system. Sure it's better to run a separate stripped down web server but for people who don't mine having mod_python instances serving up images that trick will save them running more than one web server.
comment:3 by , 19 years ago
Resolution: | → fixed |
---|---|
Status: | reopened → closed |
Fixed in [260]. Added 'Serving media files' to docs/modpython.txt.
comment:4 by , 19 years ago
priority: | normal → lowest |
---|---|
Resolution: | fixed |
Severity: | normal → enhancement |
Status: | closed → reopened |
Sorry to re-open this on you...
I spent too much time trying to get mod_python to work on my Windows dev machine with no luck. Getting it setup on linux is a piece of cake, but it appears that Windows setup is an afterthought for the mod_python team (which is understandable, but its frustrating to me).
Any chance we can add a global setting called ADMIN_MEDIA_ROOT to go along with ADMIN_MEDIA_PREFIX? This would allow people to leverage the AdminMediaHandler if they desire, to make delivering of image and css files thru djanog possible.
I set this up on my local machine and would like to see it folded into the project. If not, I can just create my own MediaHandler class in my project and create my own runner function.
Inside of the basehttp.py file we could then allow the overriding of the admin_media directory:
class AdminMediaHandler: def __init__(self, application): ... if settings.ADMIN_MEDIA_ROOT: self.media_dir = settings.ADMIN_MEDIA_ROOT else: self.media_dir = django.__path__[0] + '/conf/admin_media' self.media_url = settings.ADMIN_MEDIA_PREFIX
Then in global_settings.py,
# URL prefix for admin media -- CSS, JavaScript and images. Make sure to use a # trailing slash. # Examples: "http://foo.com/media/", "/media/". ADMIN_MEDIA_PREFIX = '/media/' # Absolute path to the directory that holds admin media. ADMIN_MEDIA_ROOT = None
comment:5 by , 19 years ago
Resolution: | → wontfix |
---|---|
Status: | reopened → closed |
Django isn't intended to serve media. It's your responsibility to serve them via a method of your choosing. I'd recommend lighttpd or a trimmed-down version of Apache.
comment:6 by , 19 years ago
Just as a side note: if one is so inclined, one could use my filebrowser sample to deliver media directly with django. It might not be a good idea on production systems (although there _might_ be situations where media are better served by django, for example to control access with django permissions), but it might help people with development: you just need django running and would add your media roots to the filesystem list and could serve stuff from there directly.
comment:7 by , 19 years ago
Just a comment. I have to throw my $0.02 in with Ian here, and his suggestion to add ADMIN_MEDIA_ROOT. Of course the framework isn't intended to serve media...but you're gotten a lot of new fans recently, and we LOVE the up-and-running fast nature of the project. I realize you don't see a big deal in just running a separate apache and/or lighttpd server to serve media. But when I'm trying to get a little mini dev environment going on my laptop, in a plane, why make me bother with that just to serve up my CSS files for rendering? Sure, peformance will suck, but it's the basehttp server anyway! All I really need is to be able to override the conf/admin_media (as Ian solves above perfectly), so that I can serve up the files. (I've already patched basehttp...thanks for the idea, Ian!)
Does that make sense? I know it's a different problem space than you may be used to, but it's real. A buddy of mine and I that both got this up and running this week have been ranting over this in IM for an hour now...*grin*. Throw a guy a bone!
By the way...this framework ROCKS. Regardless, I'm not going anywhere. I love it!
comment:8 by , 19 years ago
Correction. I'm actually using:
try: from django.conf.settings import ADMIN_MEDIA_PREFIX self.media_dir = settings.ADMIN_MEDIA_ROOT except AttributeError: self.media_dir = django.__path__[0] + '/conf/admin_media'
and setting a custom ADMIN_MEDIA_ROOT in myproject.settings.main
It's a hack, but it's easy to understand, and it seems to work.
comment:9 by , 19 years ago
Frack. That change seems to be shared by both my admin and "main" sites, when in development mode. So my admin CSS gets changed as well, which sucks. Dang. I think I'd rather work on my site stuff right now, so I'll deal with this later. Oh well!
comment:10 by , 19 years ago
Ugh. I've been up too long or something. How many errors in only 5 lines? *sigh* But now I realize I don't want to use ADMIN_MEDIA_ROOT anyway. You guys definitely know what you're doing...you've seen these requests before, haven't you? *grin*
Thanks for the great framework.
comment:11 by , 19 years ago
Quick and Dirty Workaround for CSS (but works for images too)
Create a directory to contain your media/css/images etc. etc.
create the following view:
from django.utils.httpwrappers import HttpResponse import os def media(request, file_name): res = HttpResponse() path = os.path.join('/path/to/your/media/dir/', file_name) f = open(path, 'rb') res.write(f.read()) res['Content-Type'] = 'text/css' return res
Then add this to your urls.py
(r'^media/(?P<file_name>\S+)', 'dotted.notation.to.your.view.media'),
you can then access your media under /media/* in your browser.
Subdirectories work too (e.g. /media/css/mystyle.css)
WARNING! This is very insecure as the filename is not sanitized in any way.
I need it for CSS but most browsers dont care if you deliver an image as text/css.
Be sure to remove this before you deploy your app.
comment:12 by , 19 years ago
Thanks for that bit of view code there. It's a great help for setting up a rapid dev enviroment, although far from a perfect solution as you mention.
It's extremely frustrating that the base http server (which isn't meant for production anyway) won't just stream bytes for media. It's even more frustrating that an exception is made for the admin app. As a neophyte, I spent an inordinate amount of time trying to figure that out until someone on IRC kindly explained the situation to me. Anyway, it seem trac doesn't have a voting feature, so please consider this comment as my support for the issue.
comment:13 by , 19 years ago
You could probably just run a SimpleHTTPServer instance to serve media files in your dev. environment, and just reference localhost:<alt. port> (i.e. 8080 here ) for your media.
e.g.
# From http://effbot.org/librarybook/simplehttpserver.htm import SimpleHTTPServer import SocketServer # minimal web server. serves files relative to the # current directory. PORT = 8080 Handler = SimpleHTTPServer.SimpleHTTPRequestHandler httpd = SocketServer.TCPServer(("", PORT), Handler) print "serving at port", PORT httpd.serve_forever()
comment:14 by , 19 years ago
I'll have to give that a try. Thanks for the info. It's still a workaround for something that should be fixed natively though I think. In talking on IRC, I'm apparently not the only one that spent an inordinate amount of time trying to figure out why the admin app can do it but user apps cannot. Additionally, asking someone to set all this up to serve CSS files, yet explaining to him that you can start developing with django in no time is a bit disingenuous.
comment:15 by , 19 years ago
There is a solution in core: just use the django.views.static.serve view function. Look at the source for documentation.
Django isn't intended to serve media. It's your responsibility to serve them via a method of your choosing. I'd recommend lighttpd or a trimmed-down version of Apache.