Search code examples
pythonhtmldjangomodelimagefield

Django ImageField will not display on webpage


I am using an imageField in my Django model and the photo is not being recognized when I try to display it in the html.

Here is my models.py

from django.db import models

class LatestRelease(models.Model):
    title = models.CharField(max_length=50)
    description = models.CharField(max_length=300)
    cover = models.ImageField(upload_to='personal/static/img/')
    display = models.BooleanField(default=True)

Here is view.py

from django.shortcuts import render
from personal.models import LatestRelease

def index(request):
    releases = LatestRelease.objects.all()
    return render(request, "personal/home.html", {'releases': releases})

HTML code

 {% for release in releases %}
    <img src="{{ release.cover.url }}" class='' height='235' width='235'>
 {% endfor %}

So basically, the image path {{ release.cover.url }} is /personal/static/img/[image name] and my photos only appear to show up when I use the url path /static/img/[image name] as the source.

Is there anyway to take /personal out of the string that is created from {{ release.cover.url }} ? Or to make it so that my img source accepts files under /personal/static/img/[image name]?


Solution

  • It might help if you showed your settings.py and urls.py files too but I'm guessing that your development server is not set up to serve that personal/static/img/[image name] file. To set that up you need to adjust your settings.py and main project urls.py files.

    settings.py:

    # Add these
    MEDIA_ROOT = os.path.join(BASE_DIR, "media")
    MEDIA_URL = "/media/"
    

    MEDIA_ROOT indicates where files can be served from when your MEDIA_URL is hit (like when your browser asks for that picture). To actually serve the files you need to set up a view, there is a built-in helper function for serving this files in development, add this to your main project urls.py file

    urls.py:

    from django.conf import settings
    from django.conf.urls.static import static
    
    
    urlpatterns = [
        # your other views
        ] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
    

    Then you should just upload the picture again, it will be saved in media/<upload_to>/<picturename>, in your case media/personal/static/img/<picture_name>. And your server will actually know where to find it now.

    Check out the documentation for a little better example.

    P.S.

    The hard-coded url that you used, /static/img/[image name] worked because the Django development server can, by default, serve static files from the static/ directory in the project root as well as any static/ folders in the application root directories. So it was a kind of happy coincidence that your upload_to arguement in your ImageField created that /personal/static/ folder. Then since DEBUG = True was set in settings.py you were setup to serve it automatically. This is described (better) in the linked documentation above.