开发者

can't figure out serving static images in django dev environment

开发者 https://www.devze.com 2022-12-22 20:36 出处:网络
I\'ve read the article (and few others on the subject), but still can\'t figure out how to show an image unless a link to a file existing on a web-service is hard-coded into the html template.

I've read the article (and few others on the subject), but still can't figure out how to show an image unless a link to a file existing on a web-service is hard-coded into the html template.

I've got in urls.py:

...        
(r'^galleries/(landscapes)/(?P<path>.jpg)$', 
    'django.views.sta开发者_开发问答tic.serve', {'document_root': settings.MEDIA_URL}),

...

where 'landscapes' is one of the albums I'm trying to show images from. (There are several more of them.)

In views.py it calls the template with code like that:

...
<li><img src=160.jpg alt='' title='' /></li>
...

which resolves the image link in html into:

http://127.0.0.1:8000/galleries/landscapes/160.jpg

In settings.py I have:

MEDIA_ROOT = 'C:/siteURL/galleries/'
MEDIA_URL = 'http://some-good-URL/galleries/'

In file system there is a file C:/siteURL/galleries/landscapes/160.jpg and I do have the same file at http://some-good-URL/galleries/landscapes/160.jpg

No matter what I use in urls.py — MEDIA_ROOT or MEDIA_URL (with expectation to have either local images served or from the web-server) — I get following in the source code in the browser:

<li><img src=160.jpg /></li>

There is no image shown in the browser.

What am I doing wrong?


This is a long post, basically summarizing all the things I learned about Django in order to get static files to work (it took me a while to understand how all the different parts fit together).

To serve static images in your development server (and later, your real server), you're going to have to do a few things (note specifically the third and fourth steps):

Set MEDIA_ROOT

MEDIA_ROOT is a constant which tells Django the physical path of the file (on your filesystem). Using your example, MEDIA_ROOT needs to be set to 'C:/siteURL/galleries/', like you wrote. MEDIA_ROOT is going to be used in one of the following steps, which is why we set it.

Set MEDIA_URL

MEDIA_URL is the "url" at which your images sit. In other words, whenever you want to get an image, the url to look for starts with MEDIA_URL. Usually this is not going to start with "http", since you're serving from your own server (my MEDIA_URL is usually set to '/site_media/', meaning to start from the root domain, then go to site_media etc.)

Use MEDIA_URL

MEDIA_URL doesn't work by magic, you actually have to use it. For example, when you're writing the HTML which gets a file, it needs to look like this:

<li><img src="{{MEDIA_URL}}/160.jpg" /></li>

See how I'm telling the template to use the MEDIA_URL prefix? That eventually translates to 'http://some-good-URL/galleries/160.jpg'.

Note that to be able to actually use the MEDIA_URL in your templates, you're going to have to add the line 'django.core.context_processors.media' to your TEMPLATE_CONTEXT_PROCESSORS setting in your settings.py file, if I'm not mistaken.

Make your dev server serve static files

In a real environment, you will configure files with addresses like "static_media" to be served without going through Django. But in a dev environment, you'll want to server them from Django as well, so you should add this generic line to the end of your urls.py file:

if settings.DEBUG:
# Serve static files in debug.
urlpatterns += patterns('',
    (r'^site_media/(?P<path>.*)$', 'django.views.static.serve',
    {'document_root': settings.MEDIA_ROOT,
    'show_indexes' : True}),
)

Note how that takes anything with the url "site_media/*" (which is actually my MEDIA_URL) and serves it from my MEDIA_ROOT folder, which is the place where the MEDIA_ROOT setting comes into play.

Final note

What confused me is that a lot of the things here are for convenience. For example, MEDIA_ROOT is only used in your debug url pattern, to tell Django where to load from. And MEDIA_URL is only there to encourage you not to put in absolute URLs in all your HTML files, because then when you decide to move the files to a different server, you'd have to manually change them all (instead of just changing the MEDIA_URL constant).

Of course, none of this is necessary: you can hard-code the debug url patter with your own folder, make sure that the static files really are being server from the url (by visiting it in your browser), and then hand-code that without using the MEDIA_URL setting into the HTML file, just to make sure things work.


This looks buggy...:

r'^galleries/(landscapes)/(?P<path>.jpg)$'

this RE will only match image names with a single character begore the jpg suffix, not four (as in, e.g., '160.jpg'). Maybe you meant...

r'^galleries/(landscapes)/(?P<path>.*jpg)$'

...?


Take this as a cross between the two previous answers, both of which are good. First, your regex is incorrect as Alex pointed out. I would suggest setting it as:

   (r'^local_media/(?P<path>.*)$', 'django.views.static.serve',{'document_root': settings.MEDIA_ROOT}), # static content

Because you're probably going to want to server css and js files too, not just images. This regex takes care of any and every static file you might want to serve.

Next, you'll want to specify the MEDIA_URL for your img tags. You currently have:

<img src=160.jpg />

Instead, it needs to be something like:

<img src=[YOUR MEDIA_URL]160.jpg />

The trick I use is easy. At the top of my views.py, I have the following code:

from django.conf import settings
resp = {}
resp['MEDIA_URL'] = settings.MEDIA_URL

and then I just pass the resp dictionary to every template I render. Now I can write those same img tags as:

<img src={{MEDIA_URL}}160.jpg />

Best of all, this part of your code can be used in production as well (not the regexes, just the MEDIA_URL bit).

0

精彩评论

暂无评论...
验证码 换一张
取 消