Failing to show images in templates Django - django

I have problems showing images in my Django templates (I'm uploading the images from the admin application). I read the documentation and other posts about the upload_to and still couldn't figure it out. I tried this <img src="{{ a.image}}"/> in my template and then this <img src="{{MEDIA_URL}}{{ a.image}}"/> and same results. Here is my settings.py code :
MEDIA_ROOT = '/home/mohamed/code/eclipse workspace/skempi0/media'
MEDIA_URL = '/media/'
and finally, I tried the following in my models.py and I failed miserably:
image = models.ImageField(upload_to = "ads/")
image = models.ImageField(upload_to = ".")
and when I used image = models.ImageField(upload_to = MEDIA_URL) I got the following error
SuspiciousOperation at /admin/advertisments/banner/add/
Attempted access to '/media/cut.jpg' denied.
EDIT
Generated links are as follows :
<img src="./DSCN6671.JPG">
RE-EDIT
Here is my view:
def index(request):
spotlightAlbum = Album.objects.filter(spotlight = True)
spotlightSong = Song.objects.filter(spotlight = True).order_by('numberOfPlays')
homepage = Song.objects.filter(homepage = True).order_by('numberOfPlays')
ads = Banner.objects.all()
copyright = CopyrightPage.objects.get()
try:
user = User.objects.get(userSlug = "mohamed-turki")
playlists = UserPlaylist.objects.filter(owner = user.userFacebookId)
purchase = Purchase.objects.filter(userName = user.userFacebookId)
user.loginState = 1
user.save()
except:
user = None
playlists = None
context = {'copyright':copyright, 'ads':ads, 'spotlightSong':spotlightSong,'spotlightAlbum': spotlightAlbum, 'homepage':homepage, 'user':user, 'playlists':playlists, 'purchase':purchase }
return render_to_response('index.html',context,context_instance = RequestContext(request))
Could anybody tell me what am I doing wrong??
P.S I'm using Django 1.4

The path you provide in upload_to will be a relative path from the MEDIA_ROOT you set in your project's settings file (typically settings.py).
Your MEDIA_ROOT is where your uploaded media will be stored on disk while the MEDIA_URL is the URL from which Django will serve them.
So if your MEDIA_ROOT is /home/mohamed/code/eclipse workspace/skempi0/media and your model's image attribute is:
image = models.ImageField(upload_to = "ads/")
Then the final home on disk of your uploaded image will be /home/mohamed/code/eclipse workspace/skempi0/media/ads/whatever-you-named-your-file.ext and the URL it will be served from is /media/ads/whatever-you-named-your-file.ext
Setting your upload path to be settings.MEDIA_URL won't work because that's where the media is served FROM not where it is allowed to be stored on disk.
If you want to load your uploaded image in your templates just do this (replace whatever with the name of the variable sent from the view to the template that represents this object):
<img src="{{ whatever.image.url }}"/>
The image attribute on your model isn't actually an image, it's a Python class that represents an image. One of the methods on that ImageField class is .url() which constructs the path to the URL of the image taking into account how you set your MEDIA_URL in your project's settings. So the snippet above will generate HTML like this:
<img src="/media/ads/whatever-you-named-your-file.ext"/>
RequestContext() and settings.TEMPLATE_CONTEXT_PROCESSORS
Since the render_to_response() you are returning from your view is utilizing RequestContext() you need to make sure you have settings.TEMPLATE_CONTEXT_PROCESSORS set correctly. Check out the 1.4 docs for further clarification.

upload_to needs to be an absolute path to the directory, not the web url. So try this:
image = models.ImageField(upload_to = settings.MEDIA_ROOT)
in your templates, just use
<img src="{{ a.image.url }}">

First, I suggest to change the MEDIA_ROOT to be
MEDIA_ROOT = os.path.join(PROJECT_ROOT,'media')
this way you ensure the media directory path is right under your project root. Your MEDIA_URL is set up correctly, but it is not used when uploading a file. MEDIA_ROOT is.
Regarding the file upload, in your model set the field to be
image_field = models.ImageField('Image', upload_to='images/some_sub_folder')
Note that I didn't use neither a leading nor trailing forward slashes. The above will upload the image to PROJECT_ROOT/media/images/some_sub_folder/ with the filename and extension of the original file. Alternatively, you can alter the filename by using a callable - upload_to=filename_convetion - more info here.
In your template, you can access the image using
<img src="/media/{{ your_model.image_field }}" />
Hope this helps, cheers.

I know this question is old but I had the same problem and this solved in my case:
settings.py
import os
BASE_DIR = os.path.dirname(os.path.dirname(__file__))
PROJECT_DIR = os.path.dirname(__file__)
MEDIA_ROOT = os.path.join(PROJECT_DIR, "media")
MEDIA_URL = '/media/'
urls.py
Then, my urls.py was missing this line of code to discover the /media/ folder and show the content:
urlpatterns += staticfiles_urlpatterns()
urlpatterns = patterns('',
url(r'^media/(?P<path>.*)$', 'django.views.static.serve', {'document_root': settings.MEDIA_ROOT}, name="media_url"),
) + urlpatterns
Hope it can help someone.

Related

Django turns absolute filepaths into relative, forcing the server to be run from the project folder

I'm trying to create a website where you can add images to models, which will then be in turn loaded on the homepage. However, I've noticed that when I run my server, it tries to get images from my /home folder.
Here's my models.py:
image_directory = join(settings.STATICFILES_DIRS[0], "website/images")
class Item(models.Model):
image = models.FilePathField(path=image_directory, recursive=True)
Here's my home.html (I'm just abbreviating it, item is passed in OK:
<img src="{{ item.image }}">
I run the migrations and run the server, and I'm able to select the image in /admin. The images look like: "sub_img_folder/img.jpg"
Then I go to /home and I get the following errors:
Not Found: /home/...absolute-path-to-project.../static/website/images/sub_img_folder/img.jpg
Not Found: /home/static/website/images/sub_img_folder/img.jpg
Any help would really be appreciated.
EDIT: Here's some of my settings.py contents.
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
...
STATICFILES_DIRS = [
os.path.join(BASE_DIR, 'static'),
]
...
MEDIA_ROOT = os.path.join(BASE_DIR + "/static/website/")
MEDIA_URL = "images/"
EDIT 2: Just to clarify, the images you add to models are already on the server. You just need to clarify which image in the admin page, hence FilePathField instead of FileField. It somehow doesn't find the image when trying to load it on the home page but it successfully shows and selects in the admin page.
EDIT:
Since you are using a FilePathField, it only stores the path on disk, not the URL. The solution would be to use the MEDIA_URL in your template to formulate the URI string, something like this:
<img src="{{ MEDIA_URL }}/{{ FILE_NAME}}">
Where MEDIA_URL is your Media URL from settings.py and FILE_NAME is the name of the file itself.
It may be better to use an actual ImageField or FileField which stores all the information you need, or just have a CharField with the file name and build the URL like above.
PREVIOUS ANSWER:
Try adding the MEDIA elements to your Django settings.py. MEDIA_ROOT and MEDIA_URL tell Django how to handle user uploaded files:
In your settings.py:
MEDIA_ROOT = "/path/to/media/folder"
MEDIA_URL = '/media/'
In your urls.py:
urlpatterns = [
.......
] += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
Documentation:
https://docs.djangoproject.com/en/3.0/ref/settings/#media-root

Images not loading Django website

Images on my django website are not loading for some reason
This is my models.py
thumbnail = models.ImageField(upload_to='images/',blank=True)
This is my settings.py lines
STATIC_URL = '/static/'
MEDIA_URL = '/media/'
if DEBUG:
STATIC_ROOT = os.path.join(BASE_DIR, 'static/static-only')
MEDIA_ROOT = os.path.join(BASE_DIR, 'static/media')
STATICFILES_DIRS = (
os.path.join(BASE_DIR, 'static/static'),
)
This is my views.py
class BlogIndex(generic.ListView):
queryset = models.Entry.objects.published()
template_name = "index.html"
paginate_by = 5
In url.py
if settings.DEBUG:
urlpatterns +=static(settings.STATIC_URL,document_root=settings.STATIC_ROOT)
urlpatterns += static(settings.MEDIA_URL,document_root=settings.MEDIA_ROOT)
In index.html i did this
<img class="img-rounded" src = "{{object.thumbnail.url}}"/>
pip freeze
Django==1.11.2
django-ckeditor==5.2.2
django-crispy-forms==1.6.1
django-markdown==0.8.4
django-pagedown==0.1.3
Markdown==2.6.8
olefile==0.44
Pillow==4.1.1
The Images are getting saved in the static/media/images directory
But the images are not loading in the web page...
When i try to right-click and view the image It shows this error SCREEN SHOT
Other objects are working perfectly.. Only the images aren't loading
You need the media url in the src:
<img class="img-rounded" src = "{{object.thumbnail.url}}"/>
should be:
<img class="img-rounded" src = "{{MEDIA_URL}}{{object.thumbnail.url}}"/>
or something similar
<img class="img-rounded" src = "/static/media/uploads/{{object.thumbnail.url}}"/>
The Issue is fixed, (Got assistance from a facebook group)
The issue was a url pattern in the views.py
The screen shot that I put had a line
Raised by : blog.views.Blogdetail
Apparently i had a urlpattern
url(r'^(?P<slug>\S+)/$', views.BlogDetail.as_view(), name='entry_detail'),
My pattern for blog detail view has match \S+ - so any string of characters that has no spaces in
Which will match pretty much any pattern that hasn't matched previously and any other url pattern which are below this particular url will not be accessed
Changed the url pattern to the following and I was good to go
url(r'^(?P<slug>[-\w]+)/$', views.BlogDetail.as_view(),name='entry_detail'),
settings.py:
MEDIA_URL = '/media/'
MEDIA_ROOT = os.path.join(BASE_DIR, "media")
in this model you can see Overwrite of exist IMG, return img as base string:
models.py
from django.db import models
from django.core.files.storage import FileSystemStorage
from base64 import b64encode, b64decode
class OverwriteStorage(FileSystemStorage):
def get_available_name(self, name, max_length=700):
if self.exists(name):
os.remove(os.path.join(settings.MEDIA_ROOT, name))
return name
def upload_location(instance, filename):
return os.path.join('defaultfolder', instance.phone, filename)
class ImgModel(models.Model):
name= models.CharField(max_length=100)
img = models.FileField(storage=OverwriteStorage(),
upload_to=phone_upload_location,
null=True,
blank=True,
max_length=700)
def image_to_base64(self, model_picture_path):
if model_picture_path:
try:
with open(model_picture_path.path, "rb") as imageFile:
str = b64encode(imageFile.read())
return "data:image/jpg;base64,%s" % str.decode()
except IOError:
return model_picture_path.url
else:
return None
.html
<img src="{{ MEDIA_URL }}foo.jpg">
I faced this issue and I tried lot of things but imges wont load then I tried out a simple trick but this did the job. What I did was, in my settings.py file, I included the STATIC_DIR varaible just after BASE_DIR. Below is my settings.py file
Settings.py
#Build paths inside the project like this: os.path.join(BASE_DIR, ...)
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
TEMPLATE_DIR=os.path.join(BASE_DIR,'templates')
STATIC_DIR=os.path.join(BASE_DIR,"static")
#Other content
STATIC_URL = '/static/'
STATICFILES_DIRS=(
STATIC_DIR,
)
Check this out maybe this will help!
How to fix images answer is
mention above index.html
{% static 'travello/images/' as baseUrl %}
path
then

Django MEDIA_ROOT, MEDIA_URL etc

This is my first time using MEDIA_ROOT/MEDIA_URL and I'm a little confused by the configuration. I have an image upload form which saves the original image plus a resized copy. I want to save both images to my MEDIA folder, but separate them. Current structure:
project/
----apps/
--------appOne/
------------static/
------------templates/
------------__init__.py
------------models.py
------------urls.py
------------views.py
--------__init__.py/
----MEDIA/
----project/
--------__init__.py
--------settings.py
--------urls.py
----manage.py
I would like to save the original uploaded image to MEDIA/ and the resized image to a folder inside the MEDIA folder, like MEDIA/media/. Right now, it's nesting 3 times:
original image goes to ---> MEDIA/media/
resized image goes to ---> MEDIA/media/media
I'm almost positive I have my settings wrong but I've been fiddling with it for too long and nothing is working. It seems every tutorial configures things differently and I'm just not sure what the preferred structure is or why my current config isn't working the way I expect.
Here is my settings.py:
MEDIA_ROOT = os.path.join(BASE_DIR,'MEDIA')
MEDIA_URL = "media/"
models.py:
from django.conf import settings
from smartfields import fields
from smartfields.dependencies import FileDependency
from smartfields.processors import ImageProcessor
class Image(models.Model):
client = models.ForeignKey(Client, null=True, blank=True)
model_pic = fields.ImageField(upload_to=settings.MEDIA_URL, dependencies=[
FileDependency(processor=ImageProcessor(
format='PNG', scale={'max_width': 500, 'max_height': 500}))
])
views.py:
def upload(request):
form = ImageUploadForm(request.POST, request.FILES)
if form.is_valid():
client = Client.objects.get(id=request.session['id'])
image = Image.objects.create(client=client, model_pic=form.cleaned_data['image'])
return redirect(reverse('cphh:gallery'))
def show_images(request):
context = {
'images': Image.objects.all().order_by('-created_at'),
'media_url': settings.MEDIA_URL,
}
return render(request,'cphh/gallery.html', context)
The triple-nested uploaded images do render properly on my template:
{% for image in images %}
<img class="gallery-image" src="{{media_url}}{{ image.model_pic }}"
{% endfor %}
As per the documentation
MEDIA_ROOT is the Absolute filesystem path to the directory that will hold user-uploaded files.
Your code that pushes the uploaded Images to the root should have settings.MEDIA_ROOT/<sub-folder> instead of settings.MEDIA_URL
MEDIA_URL on the other hand is a placeholder for the url a client should hit to access your media. This is useful when you don't want to keep your media on your local filesystem, but to an external storage like amazon s3.
Using {{MEDIA_URL}} in your templates gives you a good way of not hard-coding the eventual media location.
first of all in the settings.py MEDIA_URL must be like this:
MEDIA_URL = "/media/"
Then delete MEDIA folder. Only media folder is enough.
and also if you need thumbnails for your uploaded images you can use Django easy_thumbnails package for this

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.

Django - Images not displaying properly

Currently working on a small Django e-commerce project and run into a small issue. For reference, I am using the Tango with Django book available online free.
I have an ImageField set in my models in order to specify an image for a product for the model of Product. I also have a model called Category which is referenced to the Product model using a ForeignKey.
The image uploads to the /static/products_img folder in the model, however, when the image is displayed in my template, the image links to /static/static/products_img folder. However, when I remove the /static in the model, and then upload an image through the admin interface, it uploads it to /products_img and not the static folder, in which of course it displays fine. But... it gets weirder, when I delete the newly created directory and place the image in the /product_img folder in the static folder, it still displays!
I'm so confused.
models.py
class Product(models.Model):
...
image = models.ImageField(upload_to='static/products_img', blank=True)
template.html
<img src="{{ STATIC_URL }}{{ product.image }}" alt="{{ product.name }}" />
settings.py
...
SETTINGS_DIR = os.path.dirname(__file__)
PROJECT_PATH = os.path.join(SETTINGS_DIR, os.pardir)
PROJECT_PATH = os.path.abspath(PROJECT_PATH)
...
STATIC_PATH = os.path.join(PROJECT_PATH,'static')
STATIC_URL = '/static/'
STATICFILES_DIRS = (
STATIC_PATH,
)
I think you have a confusion between static and media files. Static files are bundled with your apps (CSS, JS...), while media files are uploaded by users.
From what I understand, your products images are Media files, not Static files.
What if you replace your template part with:
<img src="{{ product.image.url }}" alt="{{ product.name }}" />
and your model with :
image = models.ImageField(upload_to='products/img', blank=True)
And add the corresponding settings into your settings.py :
PROJECT_PATH = os.path.abspath(os.path.dirname(__file__))
# with this, your media directory will be the same directory than your settings.py file
# you can also use a standard path like "/var/www/media"
# IMPORTANT : In any case, you have to create the directory by hand
MEDIA_ROOT = os.path.join(PROJECT_PATH, "media")
MEDIA_URL = "/media/"
If you upload an image into a product, it should now be saved under MEDIA_ROOT directory. The URL displayed in template should be /media/projects/img/image_name.