简体   繁体   中英

Not being able to set the path for an image related to a model properly in Django

I need to set a profile picture for a model in Django. I am using Pillow. My problem is that the path that I set on models.py (where the images go when I upload them using admin) is not the same as the one used by the template and so the images never show.

My static folder is in the app's folder (this is a simple project with just one app) but admin uploads the images in some folder outside the app folder.

This my code in models.py:

def get_image_path(instance, filename):
    return os.path.join('static/artists/images', str(instance.id), filename)

class Artist(models.Model):
    name = models.CharField(max_length=255)
    soundcloud = models.URLField(max_length=255, blank=True, null=True)
    description = models.TextField()
    profile_picture = models.ImageField(upload_to=get_image_path, blank=True, null=True)
    current_roster = models.BooleanField(default=True)

    def __str__(self):
        return self.name.encode('utf8')

And this is the code in the template:

{% if artist.profile_picture %}
                <img src="{{ artist.profile_picture.url }}" alt="Artist pic" style="width: 200px;">
{% endif %}

Can somebody help me please? Thanks in advance!

First of all: django provides 2 separate sets of files: static and media and their usages are different:

  • static files are served with your project code and are connected to that code. This can be for example CSS files, JavaScript, images that are part of your style or HTML layout in general.
  • media files are uploaded into your project by scripts, in admin etc and are connected with data in your database. This can be photo in your article, avatar of user on your site etc.

Both groups of files should be served directly by your HTTP server. Both files are kept inside global folders for each project - in case of static files: they are collected from all of used apps, in case of media files: they are uploaded from web. None of them should be served from app directory.

Secondly: you shouldn't specify static or media folder in upload_to, it will be added by django based on your settings.

This should work well for you and you are working with media files not static which I made all the proper switches down below, static files are css js, and images not downloaded by the users themselves. But if you have any questions please leave a comment.

settings.py - add this to your context_processors, and make sure you media root and media URL are configured this way

  TEMPLATES = [
      {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [],
        'APP_DIRS': True,
        'OPTIONS': {
           'context_processors': [
              'django.template.context_processors.debug',
              'django.template.context_processors.request',
              'django.contrib.auth.context_processors.auth',
              'django.core.context_processors.media', ###add this string here 
              'django.contrib.messages.context_processors.messages',
            ],
         },
      },
   ]

  MEDIA_URL='/media/'
  MEDIA_DIRS=[os.path.join(BASE_DIR, 'media')]

models.py - media/media/images/1/file.jpeg <--- the path, the rest of your models look fine

def get_image_path(instance, filename):
  return os.path.join('/media/images', str(instance.id), filename)
  ###### added media to the path #######

template.html - make the changes I made to your html the path should show up as media/media/images/instance.id/profile_picture.jpeg, the instance.id and file name are made up but you get what I am saying.

  {% if artist.profile_picture %}
      <img src="{{ MEDIA_URL }}/{{ artist.profile_picture }}" alt="Artist pic" style="width: 200px;">
  {% else %}
      <p> you can download a picture one day. </p>
  {% endif %}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM