Question

My problem is that I can't serve the images I save, via the admin interface of my app. Or rather I can, but through a roundabout way - which I'm sure isn't the right way. The website is meant to be about wine. There's an admin side that allows the user to write a review, and save a picture of the bottle. That seems to work well, but when I try to serve that image on the webpage there are various errors. The app is called turkishwine. I'm using Django 1.6.

Here's the setup:

1) The model.py file:

from django.db import models

class Wines(models.Model):

    wine_winery = models.ForeignKey(Winery)
    wine_name = models.CharField(max_length=200)
    wine_image = models.ImageField(blank=True, upload_to='static/images/wine/')
    ....

    def __unicode__(self):  # Python 3: def __str__(self):
        return self.wine_name

2) I have a file structure like this, and the images do save from the admin side to static/images/wine:

├── db.sqlite3
├── manage.py
├── static
│   └── images
│       ├── wine
│       │   ├── bottle_example2.png
│       │   ├── Buzbag-Rezerv-2008.png
│       │   ├── Imperial-Export-2005.png
│       │   └── Versus-Syrah-Viognier-2013.png
├── turkishwine
│   ├── admin.py
│   ├── __init__.py
│   ├── models.py
│   ├── templates
│   │   └── turkishwine
│   │       ├── index.html
│   │       ├── individualwine.html
│   │       └── wines.html
│   ├── tests.py
│   ├── urls.py
│   ├── views.py
└── wilswebsite
    ├── __init__.py
    ├── settings.py
    ├── urls.py
    ├── wsgi.py

3) The settings.py file includes the following:

INSTALLED_APPS = (
    ...
    'django.contrib.staticfiles',
    'turkishwine',
)

STATIC_URL = '/static/'
STATICFILES_DIRS = (
    os.path.join(BASE_DIR, "static"),
    '/var/www/static/',
)

4) The views.py is like this:

from django.http import HttpResponse
from django.shortcuts import render
from turkishwine.models import Wines 

def wines(request, id):
    individual_wine = Wines.objects.get(pk=id)
    context = {'individual_wine': individual_wine}
    return render(request, 'turkishwine/individualwine.html', context)
...

5) The urls.py includes:

from django.conf.urls import patterns, url
from turkishwine import views
from django.conf import settings
from django.conf.urls.static import static

urlpatterns = patterns('',
    url(r'^$', views.index, name='index'),
    url(r'^wines/(?P<id>\d+)/$', views.wines, name='wines'),
  ...
) + static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)


Here's the problem(s):

A) The admin side successfully shows a button for upload. I upload the image (which appears in the static/images/wine folder), and it lists on the admin form as

Wine image: Currently: static/images/wine/Versus-Syrah-Viognier-2013.png

However when I click on the blue link to check the picture I get a 404 that says:

Request URL: 127.00.00.1:8000/admin/turkishwine/wines/2/static/images/wine/Versus-Syrah-Viognier-2013.png/

wines object with primary key u'2/static/images/wine/Versus-Syrah-Viognier-2013.png' does not exist.

Note that the URL is not ..../static/images/wine/Versus-Syrah-Viognier-2013.png/, but .../**admin/turkishwine/wines/2/**static/images/wine/Versus-Syrah-Viognier-2013.png/

I can retrieve the image by navigating to 127.00.00.1:8000/static/images/wine/Versus-Syrah-Viognier-2013.png/. However it seems that there's something wrong with either the admin side or the directory structure, but I can't work out what. Why does it add the admin/turkishwine/wines/2/ to the URL?

B) I can, in the template (individualwine.html), retrieve the picture by going back three directories with the following:

{% load staticfiles %}
<img src= "../../../{{ individual_wine.wine_image }}"/>

but not with the method listed in https://docs.djangoproject.com/en/1.6/howto/static-files/ which suggests:

{% load staticfiles %}
<img src="{% static "{{ individual_wine.wine_image }}" %}"/>

which results in the URL: 127.00.00.1:8000/static/{{ individual_wine.wine_image }}

There's obviously something wrong with my setup but I'm at a loss to know where. Any help very much appreciated.

Was it helpful?

Solution

ImageField inherits from FileField https://docs.djangoproject.com/en/dev/ref/models/fields/#imagefield

and upload_to parameter takes a relative path that is appended to the MEDIA_ROOT setting https://docs.djangoproject.com/en/1.6/ref/models/fields/#django.db.models.FileField.upload_to

do something like this

settings.py

import os
....
BASE_DIR = os.path.dirname(os.path.dirname(__file__))
MEDIA_ROOT = os.path.abspath(os.path.join(BASE_DIR, 'media'))
MEDIA_URL = '/media/'

models.py

class Wines(models.Model):
    ...
    wine_image = models.ImageField(blank=True, upload_to='wine')
    ....

they will be uploaded to /media/images/wine and everything should work properly, you should be able to access them from your templates with something like this

 <img src="{{ individual_wine.wine_image.url }}"/>

if you want to be able to see models images from the admin list as well then take a look at https://github.com/20tab/twentytab-image-ui , it's easy and useful !

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top