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

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.static.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).

Related

Can't load local images with HTML

I am developing a simple site with Django, and wanted to load some images locally to some pages. But it doesn't load for some reason. I know there are similar questions, and from what I understand;
a-) It can be a directory problem, html file and img file is in the same directory. Still doesn't work; directory, and the html file. I tried moving the img.jpg to the templates/images directory and try <img src="images/img.jpg" height="400" width="374"> within the html file but that didn't work either.
b-) It could be a typo, but from the images up there that shouldn't be the case either.
c-) Files could be corrupted, I can open the image with browsers and tried using different images too.
d-) Img could be restricted, but that is not the case either. I think.
Trying to fix this for two days now, thought for some reason usage of extend or block might cause some problems and tried without them, still no good. and as I said its only a problem with local files. Can use files with direct link.
settings.py
# add this to your settings.py
import os
STATIC_URL = '/static/'
STATIC_ROOT = os.path.join(BASE_DIR, 'static/')
Then create a folder named static inside your app's folder. Then create another folder with the same name as your app inside that static folder.
The resulting structure should be: your_project_name/your_app_name/static/your_app_name/
You can also create a folder named images inside that last folder.
The resulting structure should be: your_project_name/your_app_name/static/your_app_name/images/
Place your image (let's call it my_image.jpg) insite that images folder.
Now in your template you can use the static tag:
{% load static %}
...
<img src="{% static 'your_app_name/images/my_image.jpg' %}" alt="">
More info here: https://docs.djangoproject.com/en/4.0/howto/static-files/
django serve html with views:
class MyTemplateView(TemplateView):
template_name = 'my.html'
for template in Django exists template settings.
https://docs.djangoproject.com/en/4.0/ref/settings/#std-setting-TEMPLATES
templates should be in special folder.
Images Django takes from media or static settings.
https://docs.djangoproject.com/en/4.0/ref/settings/#media-root
images should be in special folder.
Try configuring your project accordingly for Django-Project.

Django: static files vs. other data files

If I want to display images in a template, the path I specify is relative to the static folder in my app directory. But if I want to load a file from a view function, then the path I specify seems to be relative to the project directory. Should these files all be in the same directory? Or is it typical to separate them out in this way? Is a file loaded by a view function (such as a text file containing human-readable settings) considered to be "static" in the same sense as image, css and js files for rendering my template?
Django supports two different things: static and media files. Static files (CSS, JavaScript, Images) are the files that are part of your website. User uploaded content like images or videos are uploaded to MEDIA_ROOT. You can use these two settings to control this:
MEDIA_ROOT = '/absolute/path/to/media'
MEDIA_URL = '/media/'
Using dev server, you might need to add this to your URLs,
urlpatterns = patterns('',
# ... the rest of your URLconf goes here ...
) + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
Using file upload fields (FileField, ImageField), you can get the file url using url property which will include the defined MEDIA_URL.
No, you should not mix up true static content with package data files. Among other things, you generally don’t want users to be able to read those data files directly. Instead, place your files somewhere else within your package’s directory, then use pkgutil.get_data to read them.

Regular expressions in django url

My URL regular expression is r'^admin.*/static/admin/(?P<path>.*)$', now it can match admin/static/admin/css/base.css or admin/123/static/admin/js/actions.js, but I want it match url like admin/blog/post/static/static/admin/js/actions.js (now it doesn't match that)
How could i do that?
Thanks for everyone's comments.
My problem is I set up static url path in django to store my css/js file,like this url(r'^static/(?P<path>.*)$', 'django.views.static.serve', {'document_root': settings.STATIC_ROOT,}),
settings.STATIC_ROOT is os.path.join(os.path.dirname(os.path.abspath(__file__)), 'static')
But when I access admin interface, all css/js files are missing. because admin css file store in django\contrib\admin\static\admin and its url in html file is 'static/admin/css/base.css'. there is no this file in my static path I set in settings.
My solution is set another url like r'^admin.*/static/admin/(?P<path>.*)$', and set document root to django admin static file path. but just as i mentioned, when i go admin main page, everything is ok, my when i go deep like "add User" page, css file is still missing.
I also found a solution is change my url regular to r'.*/static/admin/(?P<path>.*)$', that's fine for everything, but is there any better solution?
After I run collectstatic,in my static path, i can found admin folder and its css/js files. then i set my url path to url(r'^admin/static/(?P.*)$','django.views.static.serve',{'document_root'‌​:settings.STATIC_ROOT}), ,it works for main admin page, but when i access http://localhost/admin/sites/site/static/static/admin/js/admin/RelatedObje‌​ctLookups.js it still doesn't work, how could I write my url path?
The pattern matches just fine:
>>> import re
>>> p = re.compile(r'^admin.*/static/admin/(?P<path>.*)$')
>>> p.match("admin/blog/post/static/static/admin/js/actions.js").groups()
('js/actions.js',)
so not clear why it didn't work for you. Have you double-checked that the problematic URL doesn't match some other, earlier regexp?
EDIT: Based on updates above, it may be that STATIC_URL isn't properly set (an empty string, perhaps?). It should point to where the static files are served from (URL, not directory) and must end with a slash. See Settings: STATIC_URL.
(And as a footnote, you should be a bit careful with having your URL regexps do too much; you're not there yet with this one, but Wikipedia's ReDoS article is good to read before you go beyond what you're doing here.)

I'm using django framework. i'm stuck up with how to show image on my home page

I'm new to django framework .I just want to show simple image on my home page (localhost:8000). I'm getting confused how to use models.py, views.py and urls.py. Can you help me to show just simple image file.
Thank you.
If you just want to display static image, django docs for managing static files and django.contrib.staticfiles may help.
You can
edit your project's settings.py and add appropriate static files settings
# Absolute path to the directory static files should be collected to.
# Don't put anything in this directory yourself; store your static files
# in apps' "static/" subdirectories and in STATICFILES_DIRS.
# Example: "/home/media/media.lawrence.com/static/"
STATIC_ROOT = '/path/to/static/root/directory'
# URL prefix for static files.
STATIC_URL = '/your_static_url_prefix/'
STATICFILES_DIRS = (
'/path/to/your/static/directory',
)
put your image somewhere under you STATICFILES directory, example at
'/path/to/your/static/directory/images/theimage.png'
Display the image from your home page template, example by
<img src="{{STATIC_URL}}images/theimage.png"/>
You can also read tutorials from the official django documentation to know the basics on how models,views,urls and templates work.
I think you should read something about it. There are some good tutorials in the net. First of all check django book, you can also watch this video tutorial

Django: css referencing media in static files (django dev / 1.3 / static files)

Like any other user of django user I serve static files. I've chosen to use django-staticfiles to be ready for django 1.3 which will basically integrate it into the core.
My question is pretty simple really - this works great for pulling together multiple media sources and referencing them in a uniform way in django templates. However, I often use image backgrounds in Css like so:
#itemname { background-image: url('/path/to/image.png'); }
My question is simple - if I use absolute names, I have to hard code them. If I use relative names, moving to "subdirectory" urls messes up the resource location for these items and they can't be loaded.
So, how do I extend this solution to CSS? Said solution must avoid:
Embedding css in html. I personally avoid this.
Using hardcoded urls. This does not work very well because on my local setup I typically use 'localhost/project' with apache for testing (mod_wsgi) whereas I tend to use project.com for deployment.
Ideas?
You said you had trouble with relative paths, but I don't understand exactly what you meant.
I ran into the same issue, and I've used relative paths to solve it. The only thing to keep in mind is that when deploying the images need to (obviously) remain in the same path relative to the CSS files.
My setup in a nutshell:
Note I'm still using django-staticfiles with Django 1.2, but it should work similarly for Django 1.3
STATIC_URL = "/site_media/static/"
STATIC_ROOT = os.path.join(PROJECT_ROOT, "site_media", "static")
STATICFILES_DIRS = (
os.path.join(PROJECT_ROOT, "static_media"),
)
Then I serve the CSS from {{ STATIC_URL }}css/style.css which references images at ../images/logo.png.
and my project looks like this:
project_dir
...
stuff
static_media
...
css
images
Let me know if you have any questions, and I'll clarify.
Ok,
I don't know if there is something wrong with #John's solution but it didn't worked to me then I put this code on the CSS
{% load static %}
{% get_static_prefix as STATIC_PREFIX %}
and
<link rel="stylesheet" href="{{ STATIC_PREFIX }}css/main.css">
Hope it helps!

Categories

Resources