view images uploaded from admin on html in django - django

I am learning to write a Django app which will fetch all images from os.path.join(BASE_DIR, 'media_root', 'uploads') and show it on html page.
But its not working like so.
admin.py
from .models import Experience
# Register your models here.
admin.site.register(Experience)
settings.py
MEDIA_ROOT = os.path.join(BASE_DIR, 'media_root')
MEDIA_URL = '/media/'
models.py
class Experience(models.Model):
id = models.AutoField(primary_key=True)
image = models.ImageField(upload_to='uploads/', default='newbalance.jpg', height_field=None, width_field=None)
studio_name = models.CharField(max_length=255)
designation = models.CharField(max_length=255)
duration = models.CharField(max_length=255)
description_short = models.TextField()
description_long = models.TextField()
keywords = models.CharField(max_length=255)
date = models.DateTimeField('DateAdded',
auto_now=True, auto_now_add=False)
class Meta:
db_table = "experience"
def __str__(self):
return self.studio_name + ' ' + self.duration
views.py
class ExperienceList(generic.ListView):
model = Experience
template_name = 'resumesection.html'
queryset = Experience.objects.all()
urls.py
urlpatterns = [
path('modelview/', views.ExperienceList.as_view(), name='experience_list'),
]
In error log,
2021-07-19 04:15:40,528: Not Found: /resume_site/modelview/uploads/atomic_arts.png
2021-07-19 04:15:41,239: Not Found: /resume_site/modelview/uploads/futureworks.jpg
I presume django should read image from 'MEDIA_ROOT/uploads' folder but it reads from '/resume_site/modelview/uploads/'. Which is not there.
I come close to the answer in this post Django admin view uploaded photo,
But cannot connect the dots between 'MEDIA_ROOT/uploads' and '/resume_site/modelview/uploads/'
How does viewing image, uploaded from admin, work in django. ?
EDIT: Part of resumesection.html in context
{% for exp in object_list %}
<h5>{{exp.studio_name}} | {{exp.duration}}</h5>
<img src="{{exp.image}}">
<p id="description_short_text">
{{exp.description_short}}
</p>
<p id="text" style="display:none;color:red">
{{exp.description_long}}
</p>
<h4 id='keywords_text' style="display:block;color:green">KEYWORDS</h4>
<p id='alt_text' style="display:block;color:green">{{exp.keywords}}</p>
{% endfor %}
urls.py in project
urlpatterns = [
path('admin/', admin.site.urls),
path('barefoot/', include('barefoot.urls')),
path('resume_site/', include('resume_site.urls')),
path('photo_gallery/', include('photo_gallery.urls')),
]
if settings.DEBUG: # added
import debug_toolbar
urlpatterns += [path('__debug__/', include(debug_toolbar.urls))]
urlpatterns += static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)

if you are want to fetch a file from a db & want to place in src you have to provide .url in last
so use this
<img src="{{ exp.image.url }}">
instead of
<img src="{{exp.image}}">
read this for better understanding https://docs.djangoproject.com/en/3.2/topics/files/
and tell me if you still getting error

Related

Django .url not showing image in template

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”

DJANGO use of static files in combination with paths references

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

image will not display Django3 serving Angular8

similar to this SO Question but that solution would not work for me. I cannot get my image to render with the Angular frontend.
In the browser {{recipe.photo}} displays http://127.0.0.1:8000/media/images/photo1_mMxzxU0.png. From the other SO question I thought since this was an absolute url pointing to the image it would work..
html
<div *ngIf= "recipes">
<ul *ngFor ="let recipe of recipes">
{{recipe.name}}
{{recipe.photo}}
<img src={{recipe.photo}} height="150" >
</div>
models.py
class Recipe(models.Model):
name = models.CharField(max_length=30)
photo = models.ImageField(upload_to='images/', null=False, blank=False)
views.py
class RestaurantRecipes(generics.ListAPIView):
serializer_class = RecipeSerializerShort
serializers.py
class RecipeSerializerShort(serializers.ModelSerializer):
class Meta:
model = Recipe
fields = ['name','photo']
settings.py
STATIC_URL = '/static/'
MEDIA_ROOT = '/Users///backend/images/'
MEDIA_URL = '/media/'
My images are in this folder /Users///backend/images/images/IMAGES_HERE
The brackets, [], tell Angular to evaluate the template expression
try this :
<img [src]="recipe.photo" height="150" >
instead of this :
<img src={{recipe.photo}} height="150" >

Django, viewing models from different app

I am super new to python programming and django and i got the basics out of the way. I created a project with two apps, home and video. In my video models.py i have the following data:
class Video(models.Model):
name = models.CharField(max_length=200)
description = models.TextField(blank=True, null=True)
I want to do something with this in my home app in the views.py, such as display the data in an html page and currently it is set up as followed:
from video.models import Video
def display_video(request):
video_list = Video.objects.all()
context = {'video_list': video_list}
return render(request, 'home/home.html', context)
in my home.html
{% if video_list %}
{% for video in video_list %}
<p>{{ video.name }}</p>
<p>{{ video.description }}</p>
{% endfor %}
{% else %}
<p>no videos to display</p>
{% endif %}
my home.html always returns "no videos to display"
But when i query Video.objects.all() in my video app it finds 2 objects. any help is appreciated.
I decided to delete the project and started over brand new but this time I used class views instead of function views. I'm not exactly sure why it didn't run but using class views it worked like a charm. So the equivalent in class views as simple as possible is.
from video.models import Video
class IndexView(generic.ListView):
template_name = 'home/index.html'
context_object_name = 'top_three'
def get_queryset(self):
return Video.objects.all()[:3]
In settings, check the following is there.
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [],
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
],
},
},
]
It worked for me without using class. I just did what we normally do.
from django.shortcuts import render
from AllBlogs.models import Post # getting this post form AllBlogs app
# Create your views here.
def home (request):
# sort posts according to date in descending order
# only a single query is generated and then hit the database that's how this will not affect the performance of database
latest_blogs = Post.objects.all().order_by("-date")[:3]
return render(request,'Home/home.html',{'blog':latest_blogs})
And this is my template
<!--separated it from the home.html because we can use it in AllBlogs.html
and it save our work and time by just including without copying the same data several times-->
{% load static %}
<li>
<!--add field name which we used in models-->
<article class="blog">
<a href="{% url 'blogDetails_page' blog.slug %}"> <!--Different slug for different blog as slug will create a different url-->
<!--dtl filter to add back or url dynamic url creation-->
<image src="{% static 'images/'|add:blog.image_name %}" alt="{{blog.title}}">
<div class="blog__content">
<h3>{{blog.title}}</h3>
<p>{{blog.excerpt}}</P>
</div>
</a>
</article>
</li>
And this is the Post model
# having post data
class Post(models.Model):
title = models.CharField(max_length=150)
date = models.DateField(auto_now=True) # put the date in the field at which time we are saving the data
image_name = models.CharField(max_length=50) # later on we upload files right now we get images from static folder
excerpt = models.CharField(max_length=200)
content = models.TextField(validators=[MinLengthValidator(10)]) # TextFields same like CharField
slug = models.SlugField(unique=True, db_index=True) # set it as unique because we are going to use it as a primary key
author = models.ForeignKey(Author,on_delete=models.SET_NULL,related_name='posts',null=True) # one to many relation
tags = models.ManyToManyField(Tag) # ManyToManyRelation with tag
# represent post entry by it post title
def __str__(self):
return self.title

Uploaded images not showing, wrong path

I've got a problem with displaying images that were uploaded from admin panel. Django renders wrong path, probably due to my configuration mistake somewhere...
This is my model definition:
class Article(models.Model):
"""News article, displayed on homepage to attract users"""
class Meta:
db_table = 'article'
title = models.CharField(max_length=64)
headline = models.CharField(max_length=255)
content = HTMLField()
image = models.ImageField(upload_to = 'articles/', null=True, blank=True)
active = models.BooleanField()
created_at = models.DateTimeField()
def __unicode__(self):
return self.title
This is url configuration:
from django.conf.urls import patterns, include, url
from django.conf import settings
from django.conf.urls.static import static
urlpatterns = patterns('',
# some stuff
) + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
settings.py:
PROJECT_DIR = os.path.dirname(__file__)
MEDIA_ROOT = os.path.join(PROJECT_DIR, "media")
MEDIA_URL = '/media/'
the view:
def slider(request):
context = Context ({ 'articles': Article.objects.order_by('-created_at')[:5] })
return render(request, 'articles/slider.html', context)
and the template:
{% for article in articles %}
<img src="{{ article.image.url }}" alt="" />
I would expect django to render http://127.0.0.1:8000/media/articles/slide-02.jpg but now it renders http://127.0.0.1:8000/media/slide-02.jpg. I've defined the upload_to=articles/ in the model class. So why does the article.image.url attribute return a path without this significant directory?
edit: I've got something wrong with my model. It doesn't recognize the upload_to directory:
$ ./manage.py shell
Python 2.7.3 (default, Aug 1 2012, 05:14:39)
[GCC 4.6.3] on linux2
Type "help", "copyright", "credits" or "license" for more information.
(InteractiveConsole)
>>> from articles.models import Article
>>> Article.objects.all()
[<Article: Blackened Recordings Launches>, <Article: The Rockin' Return of Deep Purple>, <Article: See Emily Day 20th April>, <Article: Celebration Day Premieres In Four Countries Announced>, <Article: Waging heavy innovation>, <Article: Rush to play festival D'Ete, Quebec City>]
>>> Article.objects.all().get(pk=1)
<Article: Blackened Recordings Launches>
>>> Article.objects.all().get(pk=1).image
<ImageFieldFile: slide-03.jpg>
>>> Article.objects.all().get(pk=1).image.path
u'/var/www/django/djninja/djninja/media/slide-03.jpg'
>>> Article.objects.all().get(pk=1).image.url
'/media/slide-03.jpg'
Again, it should be media/articles/slide-03.jpg instead of media/slide-03.jpg. So I guess all routing/template is ok, something's wrong with the model.
In views.py:
from django.shortcuts import render_to_response, RequestContext
def slider(request):
articles = Article.objects.order_by('-created_at')[:5]
return render_to_response('articles/slider.html', locals(), context_instance = RequestContext(request)
In slider.html:
{% for article in articles %}
<img src="{{ MEDIA_URL }}{{ article.image.url }}" alt="" />
{% endfor %}
In urls.py:
from django.conf import settings
urlpatterns += patterns('',
(r'^media/(?P<path>.*)$', 'django.views.static.serve', {'document_root': settings.MEDIA_ROOT}),
)
Try using the above given codes.
Above solution is perfectly ok. My problem was the improperly configured fixtures written in JSON and loaded into the database. I thought that in you pass articles directory as the upload_to kwarg, it'll be dynamically loaded. It's not. It is used only during saving the image and is ignored during loading the image from the database. Thus, if I had
"image":"slide.jpg"
I changed it to:
"image":"articles/slide.jpg"
And it worked. In fact, it worked all the time, but I miss a note on that in django official docs.
Did you try to use a upload method :
def upload_path(self, filename):
return 'media/articles/%s' % filename
class Article(models.Model):
...
image = models.ImageField(upload_to=upload_path, null=True, blank=True)
...