3

I'm trying to use Django 2.0. I'm using the development 'runserver' right now, so please keep in mind that I'm not in production yet. I am familiar with the differences between the two with regard to static files.

I have a Blog Post model. In the admin, I want to be able to add an image to my model using ImageField. I'd like it to be optional, and provide a default image if none is added.

I am able to load images in admin. I am unable to render my image in my template. The console shows that Django is trying to GET my image, but my configurations have not worked so far.

Here's my model and relevant field:

from PIL import Image

class Post(models.Model):
    ....
    thumbnail = models.ImageField(default='/img/default.png', upload_to='img', blank=True, null=True)
    ....

My model works well aside from the ImageField. My View works well, and I don't think there is any issue there.

Here is my urls.py

....
from django.conf.urls.static import static
from django.conf import settings
from django.contrib.staticfiles.urls import staticfiles_urlpatterns
from . import views   

urlpatterns = [
....
path('posts/', views.PostListView.as_view(), name='post_list'),
path('post/<int:pk>/', views.PostDetailView.as_view(), name='post_detail'),
path('post/random/', views.random_post, name='random_post'),

]
urlpatterns += staticfiles_urlpatterns()
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)

I'm not at all sure about how to handle static files vs. media files in my urls.py, especially with changes to Django in version 2.0.

Here's my relevant settings.

BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
STATIC_URL = '/static/'
TEMPLATES = [
    {
        ...
        'OPTIONS': {
            'context_processors': [
                ....
                'django.contrib.messages.context_processors.media',
                ....
                ]
         },
    },
]

MEDIA_ROOT = os.path.join(BASE_DIR, 'media').replace('\\', '/') 
MEDIA_URL = '/media/'

I am equally unsure of what to put in my settings.py concerning media. My static CSS files are working just fine. I have a logo image in my static files that is rendering in my base template.

Here is my template tag for the ImageField:

<img class="card-image mr-3" src="{{ post.thumbnail.url }}" alt="Generic placeholder image">

Lastly, my /static folder and my /media folder are in the same directory. These are both in my app directory, /blog.

Can anyone see any blaring errors here, or can they make suggestions? My issue is the default image is not loading. The default image IS in the correct directory /media/img/. The console warning says "Not Found: /media/img/default.png".

Thanks in advance. Any suggestions will be helpful.

Ron Raney
  • 372
  • 2
  • 4
  • 14
  • What does `MEDIA_ROOT` evaluate to? Are you sure you need the `replace()`? I would change the default to `default='img/default.png'` without the leading slash. However I don't think either of those are the real issue here. – Alasdair Jan 16 '18 at 18:02
  • I will take out the replace() in Settings.py. I will change the leading slash. How do I evaluate MEDIA_ROOT? I copied the URL on the image. http://127.0.0.1:8000/media/img/default.png. It's not finding /media/img/default.png but the image is in those directories. – Ron Raney Jan 16 '18 at 18:07
  • Just add `print(MEDIA_ROOT)` to your settings to check its value. – Alasdair Jan 16 '18 at 18:30
  • Thank you. I solved it. I was leaving out my app name in the MEDIA_ROOT. – Ron Raney Jan 16 '18 at 19:11

2 Answers2

1

Printing the media root helped me solve this issue. Thanks Alasdair.

I don't think there was any issue with my model field above.

The urls.py code that I ended up using is directly from Django docs for Django 2.0 in handling static files https://docs.djangoproject.com/en/2.0/howto/static-files/.

The changes I made to Settings were done thanks to printing my MEDIA_ROOT in the console. I changed the syntax and the direction of a slash (blog\media). I also deleted the context processor shown above in my TEMPLATES options.

Here's what works for me:

models.py

thumbnail = models.ImageField(default='img/default.png', upload_to='img', blank=True, null=True)

urls.py

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

urlpatterns = [...] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)

settings.py

MEDIA_ROOT = os.path.join(BASE_DIR, 'blog\media')
MEDIA_URL = '/media/'

print(MEDIA_ROOT)

Template tag

<img class="card-image mr-3" src="{{ post.thumbnail.url }}" alt="Generic placeholder image">
Ron Raney
  • 372
  • 2
  • 4
  • 14
1

Django ImageField for Admin Panel

There is important thing you have to define your MEDIA_URL in urls.py. Without this definition framework doesn't gives to you permission to access image Setting.py

MEDIA_URL = '/uploads/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'uploads')

urls.py

if settings.DEBUG: # new
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)

Models.py

class Product(models.Model):
    title = models.CharField(max_length=150)
    image=models.ImageField(blank=True,upload_to='images/')

    def __str__(self):
       return self.title

    def image_tag(self):
        return mark_safe('<img src="{}" height="50"/>'.format(self.image.url))
    image_tag.short_description = 'Image'

Admin.py

class ProductAdmin(admin.ModelAdmin):
list_display = ['title','image_tag']
readonly_fields = ('image_tag',)
Yuksel CELIK
  • 113
  • 3