4

I use Django 1.9.1, Python 3.5. Code:

class Image(models.Model):
image = models.ImageField(upload_to = "shop/static/shop")
description = models.CharField(max_length = 200, blank = True)
def __str__(self):
    return self.image.url

def image_tag(self):
    return u'<img src="/%s" width="300"/>' % self.image.url[5:] #Bad code
image_tag.allow_tags = True

When object Image is created then Image.image.url=shop/static/shop/filename. I can get the image on following address: /static/shop/filename. This example is working but

return u'<img src="/%s" width="300"/>' % self.image.url[5:] #Bad code

self.image.url[5:] is bad code I think. If STATIC_URL will be changed then the code won't work. How is it possible to change the code for working with other STATIC_URL. Does exist a library handling URL?

8
  • Pleeeease indent your code properly. It's hardly readable. And elaborate a bit on what specific goal are you trying to achieve? Do you have your STATIC_URL baked in the database records? Commented Jan 14, 2016 at 17:46
  • The goal is to write a function which returns valid URL of Image. It will be used in templates in <img> tag for example. I don't know if my STATIC_URL baked in the database records. The STATIC_URL is in settings.py. Commented Jan 14, 2016 at 17:55
  • As far as I know, the url returned by instance.image.url is completely valid. More than that, it automatically changes if you change the settings.STATIC_URL. Maybe you need something like manage.py collectstatic to move your static files to the proper location? Commented Jan 14, 2016 at 18:26
  • Static files is serving in shop/static/shop (upload_to argument). And instance.image.url shows served path + filename: shop/static/shop/filename. This url isn't valid. This is path. Expected valid url is static/shop/filename. Commented Jan 14, 2016 at 18:38
  • Could you post your settings related to handling static files? All that settings.STATIC* variables. Commented Jan 14, 2016 at 18:48

2 Answers 2

13

STATIC_ROOT and STATIC_URL are for static files - files that are used by your web application and don't change by its users, i.e. static images(you site logo, backgrounds, etc). If you are using files, that are uploaded by users, images or not, MEDIA_ROOT and MEDIA_URL are used. When you define upload_to it is concatenated with MEDIA_ROOT in your settings. So i.e.:

MEDIA_ROOT='/var/www/media/'

and you define:

image = models.ImageField(upload_to = "shop/static/shop")

the image will be stored as /var/www/media/shop/static/shop/[image_name.jpg].

MEDIA_URL is the part in URL that will correspond to MEDIA_ROOT on filesystem path.

Also, if by self.image.url[5:] you're trying to get relative path, depending on your settings you might be good with using just self.image.path.

Sign up to request clarification or add additional context in comments.

3 Comments

i define upload_to = 'test', my media_root /var/www/site, from debugger image.path = /var/www/site/imagename.ext - without upload_to. phisicaly image stored by /var/www/site/text/imagename.ext why?
@Routhinator Have you read the question and my answer in full or just looked at highlighted things? If you would bother reading it, you would notice, that there's a mention of where to put static files and where to put user uploads. I see no value in your comment the way it is composed.
@Nikita Sorry I misunderstood the context and have been reading too many questions that don't answer the problem I'm dealing with. I'll remove my comment, however given my comment and the lack of an answer dealing with how to get Django to allow a default file to be in static, I think I'll be opening another question to deal with that issue.
8

Thanks Nikita! It helped me. To settings.py I added 2 lines:

MEDIA_ROOT = '/home/1234/5/6/django_app/media/'
MEDIA_URL = '/media/'

Besides that I changed models.py. Before:

class Image(models.Model):
    image = models.ImageField(upload_to = 'some_path')

After:

class Image(models.Model):
    image = models.ImageField()

I.e. images uploaded by a user download to MEDIA_ROOT path automatically.

In order to make these images available provide browser, it'd make following changes in urls.py:

from django.conf import settings
from django.conf.urls.static import static

urlpatterns = [
    url(r'^admin/', admin.site.urls),
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)

After that the image will be available in http://server.com/media/filename_of_image.

My goal was to show the image in admin control panel. After those manipulations the code in models.py will be following:

class Image(models.Model):
    image = models.ImageField()
    description = models.CharField(max_length = 200, blank = True)
    def __str__(self):
        return self.image.url

    def image_tag(self):
        return u'<img src="%s" width="300"/>' % self.image.url #Not bad code
    image_tag.allow_tags = True

1 Comment

This was a great help. Thanks. But you don't need to use an explicit path for your MEDIA_URL, if it's within your project structure. This is what I did. MEDIA_ROOT = os.path.join(BASE_DIR, 'djangoapp/media/djangoapp' ) MEDIA_URL = '/media/'

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.