Search code examples
pythondjangodjango-templatesimagefield

Django ImageField Uploaded to Different Path than Reported by url property?


I'd like to allow users to upload profile pictures and then to display them.

Here's my model.py:

from django.db.models import CharField, ImageField, Model

class Eater(Model):
    name  = CharField(max_length = 30)
    image = ImageField(upload_to = 'images/eaters/')

    def __str__(self):
        return str(self.name)

Here's my urls.py:

from django.conf             import settings  # settings is an object, not a module, so you can't import from it. :(
from django.conf.urls.static import static
from django.urls             import path
from .views                  import EaterView, IndexView, post, sudo

app_name    = 'socialfeedia'
urlpatterns = [
    path('',      IndexView.as_view(), name = 'index')
] + static(settings.MEDIA_URL, document_root = settings.MEDIA_ROOT)  # Static returns a list of path, not a path itself.

This is at the end of my settings.py:

MEDIA_URL = '/media/'
MEDIA_ROOT = BASE_DIR.joinpath('media/')

Here's a line out of my index.html:

<img class="post-profile-picture" src="{{ post.eater.image.url }}" alt="?"/>

I successfully uploaded a file into this field - it got stored at:

mysite/media/images/eaters/test_picture_64.jpg

The image loads successfully if I visit it here:

http://127.0.0.1:8000/socialfeedia/media/images/eaters/test_picture_64.jpg

However, the img that shows up in my generated file is this:

<img class="post-profile-picture" src="/media/images/eaters/test_picture_64.jpg" alt="?">

This file doesn't resolve - I just see a ? (the alt) instead. Should I be using something else to get the correct path to the file instead? Something like this maybe?

{% media post.eater.name %}

(Except no such thing as media exists as far as I can tell...)

It should be including socialfeedia/ (the app name) at the start of the url but it isn't... it doesn't seem very much like what I've seen of Django so far to expect me to manually hardcode that in...


Solution

  • my guess is to move

    + static(settings.MEDIA_URL, document_root = settings.MEDIA_ROOT)  # Static returns a list of path, not a path itself.
    

    from urls.py file of your app socialfeedia to the global urls.py file under the project package and don't forget to set the namespace socialfeedia in the corresponding urls:

    from django.conf import settings
    from django.urls import path, include
    
    from django.contrib import admin
    
    [..]
    
    urlpatterns = [
    
        [..]
    
        path('socialfeedia/', include('socialfeedia.urls', namespace='socialfeedia')),  # HERE
    
        path('admin/', admin.site.urls),  # Admin Area
    ]
    
    
    # DEBUG = True
    if settings.DEBUG:
    
        from django.conf.urls.static import static
    
        urlpatterns += static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)
        urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
    

    let me know if this helps you.