Reputation: 26467
I've got a problem with displaying images that were uploaded from admin panel. Django renders wrong path, probably due to my configuration mistake somewhere...
This is my model definition:
class Article(models.Model):
"""News article, displayed on homepage to attract users"""
class Meta:
db_table = 'article'
title = models.CharField(max_length=64)
headline = models.CharField(max_length=255)
content = HTMLField()
image = models.ImageField(upload_to = 'articles/', null=True, blank=True)
active = models.BooleanField()
created_at = models.DateTimeField()
def __unicode__(self):
return self.title
This is url configuration:
from django.conf.urls import patterns, include, url
from django.conf import settings
from django.conf.urls.static import static
urlpatterns = patterns('',
# some stuff
) + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
settings.py:
PROJECT_DIR = os.path.dirname(__file__)
MEDIA_ROOT = os.path.join(PROJECT_DIR, "media")
MEDIA_URL = '/media/'
the view:
def slider(request):
context = Context ({ 'articles': Article.objects.order_by('-created_at')[:5] })
return render(request, 'articles/slider.html', context)
and the template:
{% for article in articles %}
<img src="{{ article.image.url }}" alt="" />
I would expect django to render http://127.0.0.1:8000/media/articles/slide-02.jpg
but now it renders http://127.0.0.1:8000/media/slide-02.jpg
. I've defined the upload_to=articles/
in the model class. So why does the article.image.url
attribute return a path without this significant directory?
edit: I've got something wrong with my model. It doesn't recognize the upload_to directory:
$ ./manage.py shell
Python 2.7.3 (default, Aug 1 2012, 05:14:39)
[GCC 4.6.3] on linux2
Type "help", "copyright", "credits" or "license" for more information.
(InteractiveConsole)
>>> from articles.models import Article
>>> Article.objects.all()
[<Article: Blackened Recordings Launches>, <Article: The Rockin' Return of Deep Purple>, <Article: See Emily Day 20th April>, <Article: Celebration Day Premieres In Four Countries Announced>, <Article: Waging heavy innovation>, <Article: Rush to play festival D'Ete, Quebec City>]
>>> Article.objects.all().get(pk=1)
<Article: Blackened Recordings Launches>
>>> Article.objects.all().get(pk=1).image
<ImageFieldFile: slide-03.jpg>
>>> Article.objects.all().get(pk=1).image.path
u'/var/www/django/djninja/djninja/media/slide-03.jpg'
>>> Article.objects.all().get(pk=1).image.url
'/media/slide-03.jpg'
Again, it should be media/articles/slide-03.jpg
instead of media/slide-03.jpg
. So I guess all routing/template is ok, something's wrong with the model.
Upvotes: 2
Views: 7357
Reputation: 26467
Above solution is perfectly ok. My problem was the improperly configured fixtures written in JSON and loaded into the database. I thought that in you pass articles
directory as the upload_to
kwarg, it'll be dynamically loaded. It's not. It is used only during saving the image and is ignored during loading the image from the database. Thus, if I had
"image":"slide.jpg"
I changed it to:
"image":"articles/slide.jpg"
And it worked. In fact, it worked all the time, but I miss a note on that in django official docs.
Upvotes: 2
Reputation: 8836
In views.py:
from django.shortcuts import render_to_response, RequestContext
def slider(request):
articles = Article.objects.order_by('-created_at')[:5]
return render_to_response('articles/slider.html', locals(), context_instance = RequestContext(request)
In slider.html:
{% for article in articles %}
<img src="{{ MEDIA_URL }}{{ article.image.url }}" alt="" />
{% endfor %}
In urls.py:
from django.conf import settings
urlpatterns += patterns('',
(r'^media/(?P<path>.*)$', 'django.views.static.serve', {'document_root': settings.MEDIA_ROOT}),
)
Try using the above given codes.
Upvotes: 2
Reputation: 9275
Did you try to use a upload method :
def upload_path(self, filename):
return 'media/articles/%s' % filename
class Article(models.Model):
...
image = models.ImageField(upload_to=upload_path, null=True, blank=True)
...
Upvotes: 1