I have a django app which allows users to submit an image with it. Right now my model looks like
class Posting(models.Model):
title = models.CharField(max_length=150)
images = models.ForeignKey(Image, null=True)
class Image(models.Model):
img = models.ImageField(upload_to="photos/",null=True, blank=True)
and I am trying to display the images in my template however I cannot seem to get it to work. I have gone though countless stack overflow posts and haven't had any luck. In my template I have
{ for post in postings }
<img src"{{ post.image.url }} #and many variations of this
however other seems to display the url. The url seems to always be blank. Any help would be greatly appreciated!
This is how i got it working.
settings.py
import os
BASE_DIR = os.path.dirname(os.path.dirname(__file__))
STATIC_URL = '/static/'
STATICFILES_DIRS = (
os.path.join(BASE_DIR, "static"),
)
MEDIA_ROOT = (
BASE_DIR
)
MEDIA_URL = '/media/'
models.py
...
image = models.ImageField(upload_to='img')
urls.py(project's)
if settings.DEBUG:
urlpatterns = urlpatterns + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
template (.html)
<img src="{{ post.image.url }}" alt="img">
Do something like this. This code is working in my app.
views.py:
def list(request):
images = Image.objects.all()
return render(request, "list.html", {'images': images})
list.html:
{% for i in images %}
<img src="{{ i.image.url }}" width="500px"/>
{% endfor %}
The template tag should be:
<img src="{{ post.images.img.url }}" ... >
You should expect something akin to:
{% for post in postings %}
<img src="{{ post.image.url }}">
{% endfor %}
There are a couple of caveats here --
Images are served as a file, whatever is serving your application (runserver, nginx, apache, etc.) needs to have the ability to route that file.
You must ensure you are building the context for the template engine to use. It will silently fail on values that it cannot find in context.
It looks like you may be trying to follow a video tutorial series by Corey Schaefer. If so, my suggestion won't help, but if not, Corey Schaefer has a video that covers exactly what you're trying to do at
https://youtu.be/FdVuKt_iuSI?list=PL-osiE80TeTtoQCKZ03TU5fNfx2UY6U4p.
You have to set quite a number of settings and override some defaults. The django documentation has two ways of doing it, one for development on localhost and another for production: https://docs.djangoproject.com/en/2.2/howto/static-files/
Related
I was getting tired of figuring out how to fix this problem. I checked a lot of different posts and answers but nothing helped me.
I have a form where I'm creating new advert. I have file input there for Image.
Form is valid and everything works fine, but my problem is that when I want to display my image from Advert model then it's not showing on website.. even the alt text.
My template code:
{% for advert in adverts %}
<img src="{{ advert.get_image }}" alt="test"/>
<div class="col-lg-4 col-md-6 col-sm-6">
<div class="mb-4 card">
<div id="second-advert" class="carousel slide">
<div class="carousel-inner">
<div class="carousel-item active">
<img src="{{ advert.get_image }}" alt="test"/>
</div>
</div>
My 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('carapp.urls')),
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
My settings.py:
STATIC_URL = 'carsearch/static/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
MEDIA_URL = '/media/'
STATICFILES_DIRS = [
os.path.join(BASE_DIR, 'static'),
]
My models.py:
class Advert(models.Model):
def get_image(self):
if self.featured_image and hasattr(self.featured_image, 'url'):
return self.featured_image.url
else:
return '/path/to/default/image'
owner = models.ForeignKey(Profile, null=True, blank=True, on_delete=models.SET_NULL)
title = models.CharField(max_length=200)
[...] <-- there's more code
featured_image = models.ImageField(null=True, blank=True, default='profiles/user.png', upload_to='adverts/')
[...] <-- there's more code
def __str__(self):
return self.title
My project structure:
enter image description here
And my website:
enter image description here
The image should appears above these two containers.. but it doesn't.
When I go to admin panel I can see added image in my model and I can click it and see it.
I also can see it in my database with python shell and with DB Browser for SQLite
But when I inspect the website then I can find my img tag but it is disabled(?)
enter image description here
enter image description here
And my views.py:
def adverts(request):
adverts = Advert.objects.all()
context = {'adverts': adverts, 'profile': profile}
return render(request, 'carapp/advertsView.html', context)
I tried many things from google and nothing works.. I also can say that I have a Profile form and Profile model. And there is also a photo which I can update and everything works there..
Actually I found a solution for this problem. Maybe it’s not what I expected but it helps.
The problem was in my featured_image field in models.py. I had to remove the attr upload_to=“images/adverts”
I've posted something similar earlier without being able to find a suitable solution. One of the things I am struggling with is the ability to serve static path / file references within DJANGO html templates. Hopefully, by posting another question I will be able to understand how this works. Done quite some research and read through the DJANGO documentation without being able to find something covering my scenario.
Here we go:
Within my model I use a path reference field
class Product_images(models.Model):
product = models.ForeignKey(Products, on_delete=models.SET_NULL, blank=True, null=True)
path_to_image = models.CharField(max_length=150,null=True, blank=True)
name = models.CharField(max_length=50,unique=False,blank=True)
class Meta:
verbose_name = 'Product Image'
verbose_name_plural = 'Product Images'
def __str__(self):
return '{} - {} - {}'.format(self.pk, self.product, self.name)
The value of this field is set to (example):
static\images\Product\PowerBI\Receivables\Receivables 6.png
The files are physically stored within the app Main/static/....
My setting file contains:
STATIC_URL = '/static/'
STATIC_ROOT = os.path.join(BASE_DIR, 'static/')
MEDIA_ROOT = os.path.join(BASE_DIR, 'Main/')
MEDIA_URL = '/Main/'
Then I have two templates within the app where I want to serve these images. One page uses a custom context processor in the following way:
{{ product_section }}
Which returns html including:
html_value += u'<img class="d-block w-100" src="{}" width="400px" height="250x" alt="{}">'.format(productimages_obj.path_to_image,productimages_obj.name)
This context processor tag is used within a template returned by the products_view view function.
Now, I want to use the same images within another view gallery_view:
def gallery_view(request, requestid, *arg, **kwargs):
productimages = Product_images.objects.filter(product=requestid)
if productimages.exists() != True:
return HttpResponseNotFound('<h1>Page not found</h1>')
context = {
'productimages': productimages
}
return render(request, "gallery.html", context)
When using the following template tag {{ productimages.path_to_image }} I am getting 404 "GET /Gallery/static/images/Product/PowerBI/Finance/Finance%207.png HTTP/1.1" 404 3485.
The template is coded as following:
<section id="gallery" class="bg-light">
<div class="container-fluid">
<div class="row">
{% for productimages in productimages %}
<div class="col-md">
<img src="{{ productimages.path_to_image }}" onclick="openModal();currentSlide({{ forloop.counter }})" class="hover-shadow">
</div>
{% endfor %}
</div>
</div>
Last but not least Urls.py:
urlpatterns = [
path('', views.home_view, name='home'),
path('Home', views.home_view, name='home'),
path('PowerBI', views.products_view, name='power bi'),
path('Services', views.services_view, name='services'),
path('About', views.about_view, name='about'),
path('Contact', views.contact_view, name='contact'),
path('Gallery/<int:requestid>', views.gallery_view, name='gallery'),
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
What mistake am I making here? Why does the GET include /Gallery/ within the URL? How do I circumvent this?
Thanks everyone.
I would set an image field and in the templates I would use its URL property:
models.py:
image = models.ImageField(null=True, blank=True)
.html file:
<img src="{{object.image.url}}" alt="" class="img-fluid">
I'm trying to display already stored database image in template. But here i'm getting only name of the image. How to solve this, Where i did mistake.
models.py
class Images(models.Model):
image = models.ImageField(upload_to='images', blank=True, null=True)
settings.py
STATIC_URL = '/static/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
MEDIA_URL = '/media/'
urls.py
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
views.py
def display(request):
myimages_objs = Images.objects.all().values()
for i in myimages_objs :
myimages_objs = i['image']
return render(request, 'index.html', {'myimages_obj ': myimages_objs })
index.html
<div class="divi">
<img src="{{ myimages_obj }}" alt="image">
</div>
I don't understand why you are returning the objects inside the for loop, this causes only a single image to be displayed in the template. Instead of doing this, you can pass all the image objects in the template, then loop through the objects in the template to display the images.
You can change your view as:
def display(request):
myimages_objs = Images.objects.all() # get all the images
return render(request, 'index.html', {'myimages_objs':myimages_objs})
Then in your template:
<div class="divi">
{% for item in myimages_objs %} //loop through all the images
<img src="{{ item.image.url }}" alt="image">
{% endfor %}
</div>
Edit:
Change the upload_to to upload_to="images/".
As far as I am concerned, your images are not being stored inside the images folder as you have missed the backslash(which represents a folder name). So, the images are being saved inside the media folder.
But the image url is something like project_path/media/images/something.jpg which cannot be found as the images are not being saved inside the images folder.
Change the field as stated for new images to be stored in the specified folder. For old images, copy them to the images folder manually.
I hope this will help.
From the past 2 days i have literally lost my patience trying to make Cloudfiles work for my project(using cumulus). Here are some of the issues:
1.) Sometimes when i upload any photo using admin(creating a model and registering with admin)... the photo looks like its uploaded but when i try to either access it using a view function by Photo.objects.all() or even going to the cloudfiles control panel...the image simply doesnt open up. I get a resource not found. I check and double check if the region(chicago is default for me) settings is screwing with me....but i don't think so.
2.) I have used collectstatic method to successfully collect all static files in a container and i am able to successfully serve them. infact when i click the link(say for example) - http://ed770b871265201bf471-14f03984d90730040890dd30a2d85248.r68.cf2.rackcdn.com/admin/css/base.css
I am able to see the results and i am sure u can see it too.
But when i am trying to use them by STATIC_URL in my templates - The admin pages don't have their css working but my login/home pages are perfectly being rendered with my styles.
Here are my settings file/my view functions and anything that is important -
STATIC_ROOT = ''
STATIC_URL = 'http://ed770b871265201bf471-14f03984d90730040890dd30a2d85248.r68.cf2.rackcdn.com/'
STATICFILES_DIRS = (
os.path.join(PROJECT_DIR,'static'),
)
CUMULUS = {
'USERNAME': '***',
'API_KEY': '****',
'CONTAINER': 'photos',
'STATIC_CONTAINER':'static',
'SERVICENET': False, # whether to use rackspace's internal private network
'FILTER_LIST': [],
'TIMEOUT' : 60
}
DEFAULT_FILE_STORAGE = 'cumulus.storage.CloudFilesStorage'
STATICFILES_STORAGE = 'cumulus.storage.CloudFilesStaticStorage'
The model file part
class Photo(models.Model):
username = models.ForeignKey(User)
image = models.ImageField(upload_to='photos')
alt_text = models.CharField(max_length=255)
admin.site.register(Photo)
This is the view function as you requested kyle.
def profile_detail(request):
if request.user.is_authenticated():
username = request.user.get_username()
# userid = User.objects.get(username=username).values('__id')
userdetails = User.objects.filter(username=username)
photo = Photo.objects.get(username=request.user.id)
return render_to_response('profile_detail.html',{'userdetails':userdetails,'username':username,'photo':photo},
context_instance=RequestContext(request))
and the template for profile_detail -
{% extends 'profile.html' %}
{% load bootstrap_toolkit %}
{% block content %}
<img src="{{ photo.image.url }}" alt="{{ photo.alt_text }}" />
<br>
<p>{{ user.first_name }}</p>
<p>{{ user.last_name }}</p>
<p>{{ user.email }}</p>
{% endblock %}
I just now checked that i can view the image(No idea how) on the hosted site(production) but still can't do it in my dev environment.
Kyle can you please check if your testaccount has a picture of penguins in the 'MYProfile' page? :) Thanks for looking into it :)
The images are there, but possibly not where you expected them.
Link on your current site:
http://d12df125d01b8a258a3a-8112fdc02f7d385b44f56eb9e899d81c.r88.cf2.rackcdn.com/photos/Penguins.jpg
Where the image/file actually is:
http://d12df125d01b8a258a3a-8112fdc02f7d385b44f56eb9e899d81c.r88.cf2.rackcdn.com/photos%5CPenguins.jpg
The %5C is a \ rather than a /. This makes a difference as these are keys (key being the "path" and value being the file). You may want to check on how these were uploaded, and possibly normalize them to regular slashes (were these uploaded while you were on a Windows machine?).
I ahve this code, the trouble is few of the images are having names, but corresponding to the names the files are not present, how can i know if the images are being displayed, i mean some if statement of something like that.
<img src="{{ STATIC_URL }}images/{{web.image}}" />
The above code is used to render my django image in a template.
Thanks.
I would do this on the client side, with a javascript, just google something like: "javascript image loaded" or something.
Are you saying that the URL expanded from {{ STATIC_URL }}images/{{web.image}} is resulting in a 404 Not Found error? And you want to figure out which ones are doing this?
You'd really need to test those URLs in your view by using some python code - something from urllib maybe - but if that URL is on the same server as the one running the view then it might just hang on you.
If web is actually a database object that you are accessing (as your comment seems to point out), and that "image" is an ImageField, you could use the following :
{% if web.image %}
<img src="{% web.image.url %}" />
{% else %}
<img src="{{ STATIC_URL }}images/MyDefaultImage.png" />
{% endif %}
This way, the template will only provide the image if it exists, and provide an alternate image if not.
I apologize in advance if I misunderstood your question, I'm not so sure that I understood everything correctly.
It would be quite difficult to determine in the template whether the file actually exists or not. That would be the job of the view, assuming that {{web.image}} actually returns anything in the first place.
def my_view(request):
# some code here
import os
if os.path.exists(web.image_path): # for example
context = { 'web': web }
render_to_response('my_template.html', context, RequestContext(request)
This assumes you actually know what the full file system path to the image file is. That's not always going to be the case, especially with the staticfiles app in django 1.3.
However, I'd be a lot more concerned that sometimes images exist, and sometimes they don't. Why is that the case? Are images being deleted for some reason? If they are, you need a way of cleaning up the database.
Edit:
Since there doesn't yet seem to be an answer that you like, you should try this:
import os
class MyModel(models.Model):
image = models.Image...
# the rest of your fields
def get_image_url(self):
if os.path.exists(self.image.path):
return u'/%s/img/%s' % (self.app_label, self.image.filename)
return u'%s/img/default.jpg' % self.app_label
In your template, you then do the following:
<img src="{{ STATIC_URL }}{{ web.get_image_url }}" />
finally i have found a solution using sorl thumbnail : http://thumbnail.sorl.net/examples.html#template-examples
{% thumbnail item.image my_size_string crop="left" as im %}
<img src="{{ im.url }}">
{% empty %}
<p>No image</p>
{% endthumbnail %}
it works for me.