Django ImageField Image Not Displaying - django

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.

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',)

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">

Related

loading local files in django

I have a folder in c:\images, images here are updated by another app. Then I wanted a Django application to read those images on the admin site. The django applicationis sitting in c:\inetpub\wwwroot\myapp I have tried adding below lines in settings.py
CURRENT_PATH = os.path.abspath(os.path.dirname(__file__))
MEDIA_ROOT = os.path.join(CURRENT_PATH, '../../images').replace('\\','/')
MEDIA_URL = 'images/'
I also tried including the whole path in django admin as below in admin.py
def img_field(self, obj):
return format_html('<img src="{}" width="500" height="500" />'.format("c:\images\phot1.png"))
If i put online image link it works fine as below:
def img_field(self, obj):
img = "https://www.thebalancesmb.com/thmb/5G9LJXyFzbTVS-Fj_32sHcgJ8lU=/3000x0/filters:no_upscale():max_bytes(150000):strip_icc():format(webp)/start-online-business-with-no-money-4128823-final-5b87fecd46e0fb00251bb95a.png"
return format_html('<img src="{}" width="500" height="500" />'.format(img))
How can i get around this?
I got it I just needed to add the below lines in urls.py
from django.conf.urls.static import static
from django.conf import settings
urlpatterns = [
#urls here
]
urlpatterns += static(settings.MEDIA_URL,document_root=settings.MEDIA_ROOT)
It is working fine.

Why cannot I see the image file in django?

I tried to load an image file, but it didn't work. I uploaded the image file by admin. Thanks for the help!
here is my code
in urls.py
path('main/archive/<int:video_id>/', views.loadphoto, name='loadphoto'),
in views.py
def loadphoto(request, video_id):
target_img=get_object_or_404(Record, pk=video_id)
context={'target_img':target_img.picture}
in models.py
class Record(models.Model):
record_text = models.CharField(max_length=50)
pub_date = models.DateTimeField('date published')
picture=models.ImageField(blank=True)
def __str__(self):
return self.record_text
in img.html
<img src="target_img">
Main
First You Need To Join Your Media directory to your app
Here is the Way You Can Do That:
First You Need To Add This in Your Setting.py
MEDIA_URL = '/media/'
MEDIA_ROOT = os.path.join(BASEDIR,'your folder directory')
#for example app/media or something
Then You Need To Create Media Url Here is The Way:
Then You Need To Add in your urls.py
from django.conf import settings
from django.conf.urls.static import static
urlpatterns = [
path('main/archive/<int:video_id>/', views.loadphoto,name='loadphoto'),
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
Then You Need To Add This in Your Html File
<img src='{{ target_img.url }}'>
You Can See More Details Here:
https://docs.djangoproject.com/en/2.2/ref/models/fields/#django.db.models.fields.files.FieldFile.url
ImageField is derived from FileField. In order to display the image in your template, you should provide its url, see https://docs.djangoproject.com/en/2.2/ref/models/fields/#django.db.models.fields.files.FieldFile.url
The source attribute should instead by populated as follow:
<img src="target_img.url">

Django Media files "Could not load image" with 200 status response

I'm slightly new to Django and I'm having an issue with the ImageField field type in development environment. I'm able to upload images through the admin panel, and I have them going to my media folder location locally. But they will not render in the DOM from Django.
I'm running Django 2.1.7 and have Pillow 5.4.1 installed
My media folder is located in my base directory (same level as my manage.py file), and has a sub-directory of series (as created by my model), with all of the correct images I uploaded through the admin panel.
Within my template .html file, I am trying to load the image with:
{% load static %}
<img src="{{ s.cardImage.url }}">
And I get a 200 status response in the terminal, but the image does not render and when I inspect the image, it says "Could not load image". If I simply output {{ s.cardImage.url }} within my template, I get this path: /media/series/IMG_5776.PNG.
So I'm inclined to think that my views are correct and I'm querying the correct object from my database.
When I uploaded the image within the Admin panel, this is what it looks like: Admin Panel
If I click on that link within the admin panel (from picture above) series/IMG_5776.PNG, it takes me to this url: http://127.0.0.1:8000/media/series/IMG_5776.PNG and the DOM is blank (with a 200 status code returning from my development server).
This is where I am stumped. I've done a lot of research and I feel like I have everything properly set-up. Does anyone know what could possibly be going wrong? Help is greatly appreciated.
Relevant Settings:
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
STATIC_URL = '/static/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
MEDIA_URL = '/media/'
Model:
class Series(models.Model):
name = models.CharField(max_length=200)
slug = models.SlugField(max_length=50)
category = models.ForeignKey(Category, on_delete=models.CASCADE)
cardImage = models.ImageField(upload_to='series', default='default.jpg')
Terminal Log:
"GET /media/series/IMG_5776.PNG HTTP/1.1" 200 0
Base urls.py:
from django.contrib import admin
from django.urls import path, include
from django.conf import settings
from django.conf.urls.static import static
urlpatterns = [
path('admin/', admin.site.urls),
path('', include('blog.urls')),
]
if settings.DEBUG:
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)

MEDIA_URL Page 404 Error Django

I am running on a local server and when I go to http://127.0.0.1:8000/media/ in my browser it says page not found.
Settings:
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
MEDIA_URL = '/media/'
STATIC_URL = '/static/'
Root URL:
from django.conf.urls import url, include
from django.contrib import admin
from django.conf import settings
from django.conf.urls.static import static
urlpatterns = [
url(r'^polls/', include('mysite.polls.urls')),
url(r'^admin/', admin.site.urls),
url(r'^submit/', include('mysite.uploads.urls')),
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
Model for User Upload:
from django.db import models
class Document(models.Model):
description = models.CharField(max_length=255, blank=True)
document = models.FileField(upload_to='documents/')
uploaded_at = models.DateTimeField(auto_now_add=True)
Following the Django documentation:
Serving files uploaded by a user during development
During development, you can serve user-uploaded media files from MEDIA_ROOT using the django.contrib.staticfiles.views.serve() view.
This is not suitable for production use! For some common deployment strategies, see Deploying static files.
For example, if your MEDIA_URL is defined as /media/, you can do this by adding the following snippet to your urls.py:
from django.conf import settings
from django.conf.urls.static import static
urlpatterns = [
# ... the rest of your URLconf goes here ...
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
https://docs.djangoproject.com/en/1.10/howto/static-files/
As pointed above in the comments by Alasdair, This is the normal behaviour of Django. If you visit the full file path like 127.0.0.1/media/file.jpg, Django will render the file instead of raising a 404 error.
Why is this happening?
If you look at the source of the view that serves the media/static files, you'll find these lines:
if os.path.isdir(fullpath):
if show_indexes:
return directory_index(newpath, fullpath)
raise Http404(_("Directory indexes are not allowed here."))
What it does is, it checks if the path requested is a directory or not. If yes, then it checks if the variable show_indexes is True, then it will return the index of the files inside the media directory. Since, show_indexes is False by default, it raises 404.
To set show_indexes to True, you can do this:
urlpatterns = [
# ... the rest of your URLconf goes here ...
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT, show_indexes=True)
This won't raise the 404 and will display a list of files inside media dir.
P.S.: I don't think displaying file indices is a good idea, unless, of course, that's something you really want. It puts server under extra load to generate the indices. And someone can download the files recursively using a program like wget etc. Even those files that are meant to be private.

Django - uploading static image as default ImageField file

This is my models.py:
def get_profileImage_file_path(instance, filename):
return os.path.join('%s/uploadedPhotos/profileImages' % instance.user_id, filename)
class UserExtended(models.Model):
user = models.OneToOneField(User)
profileImage = models.ImageField(upload_to=get_profileImage_file_path, default='/static/images/myProfileIcon.png')
Now, I want the default image (which is in my static folder) to save to the path given in the
get_profileImage_file_path
function. In my settings.py, I have defined media_root and media_URL as:
MEDIA_ROOT = '/home/username/Documents/aSa/userPhotos'
MEDIA_URL = '/media/'
For some reason, when I pass the user object in the template and in the template, if I do:
<img class='profilePic' src="{{ user.userextended.profileImage.url }}" height='120px' alt="" />
No image shows up and when I open up the 'inspect element' section in chrome, it gives a 404 error saying:
GET http://127.0.0.1:8000/home/username/Documents/djcode/aS/aSa/static/images/myProfileIcon.png 404 (NOT FOUND)
even though that is the correct file path to the image. (I'm also not sure why it's giving the entire file path, isn't it just supposed to start from /static/? Even when I 'view source', the entire url is there.) How do I make it so that the default image which is located in the static folder uploads to the path provided in the
get_profileImage_file_path
function?
In general we use the config as follows for media :
BASE_DIR = dirname(dirname(abspath(__file__)))
MEDIA_ROOT_DIR = 'media'
MEDIA_ROOT = normpath(join(BASE_DIR, MEDIA_ROOT_DIR))
MEDIA_URL = '/media/'
For, development purposes set :
DEBUG = True
And in urls.py add the following :
from django.conf import settings
from django.conf.urls.static import static
if settings.DEBUG:
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
urlpatterns += static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)
Upload the image again and validate the Image, it should work now.