Django 3.0 images: Unable to display images in template - python

I have model named Book in models.py file.
And based on this model, a view has been created to display images as products.
Which renders books(products) on shop.html template.
Problem is that i am unable to get their cover images which are saved across each publishers id who is seller of those books.
This is code of shop.html (in which i am trying to display image).
<div class="container mt-4">
<div class="row">
{% for b in books|slice:":10" %}
<div class="col-lg-2 col-md-3 col-sm-4">
<div class="book-card">
<div class="book-card__book-front">
<img src={{MEDIA_URL}}{{b.cover.url}} alt="book-image">
</div>
</div>
<div class="book-card__title">
{{ b.title }}
</div>
</div>
</div>
</div>
{% endfor %}
</div>
</div>
This is the model in which i am putting covers of books against publisher's ids (names)
def book_cover_path(instance, filename):
return os.path.join(
"covers", instance.publisher.user.username, str(
instance.pk) + '.' + filename.split('.')[-1]
)
class Book(models.Model):
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
title = models.CharField('Title', max_length=255)
authors = models.ManyToManyField(Author, related_name='books_written')
publisher = models.ForeignKey(Publisher, on_delete=models.DO_NOTHING, related_name='books_published')
price = models.DecimalField('Price', decimal_places=2, max_digits=10)
description = models.TextField('Description')
upload_timestamp = models.DateTimeField('Uploading DateTime', auto_now_add=True)
categories = models.ManyToManyField(Category, related_name='book_category')
cover = models.ImageField(upload_to=book_cover_path, null=True,blank=True)
class Meta:
unique_together = ('title', 'publisher')
get_latest_by = '-upload_timestamp'
This is view in views.py
def shop(req):
bookz = Book.objects.order_by('title')
var = {'books': bookz, 'range': 10}
return render(req, 'bookrepo/shop.html', context=var)
This is media setting in settings.py
MEDIA_URL = '/media/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
This is my folder structure i did put covers in media/covers/publisher/image.jpg EVEN i tried something like this media/media/covers/publisher/image.jpg
This is structure of media directory
I am getting NOT FOUND error in django console
Not found error like these
I think this have to do something with url i m trying to create must be missing something.
Otherwise b.title is working fine. Issue is just with image retrieval.
IF anyone don't understand book_cover_path function they can just tell me the way to make url as if books are lying in media/covers/image.jpg because i am unable to do this ALSO. As,
cover = models.ImageField(upload_to='covers', null=True,blank=True)

replace this line
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
to
MEDIA_ROOT = os.path.join(BASE_DIR,'media/')
because it is the Absolute path to the directory that will hold the file.
and replace
<img src={{MEDIA_URL}}{{b.cover.url}} alt="book-image">
to
<img src="{{b.cover.url}}" alt="book-image">
and add these lines in projects url.py file
from django.conf import settings
from django.conf. urls.static import static
urlpatterns = [
path('admin/', admin.site.urls),
] + static(settings.MEDIA_URL, document_root = settings.MEDIA_ROOT)

try this on shop.html ,Check the docs here.
<img src="{{ b.cover.url }}" alt="book-image">

Related

My images are not displaying the post.photo.url call on my cpanel hosting

Hello I just put my blog online on cpanel hosting. I managed the display with the whitenoise library of python. The static images work normally. But when I call the image from blogpost to display my image does not appear with post.photo.url. I am under cpanel and I would like to ask for your help to display the images of my blog on my site
class Photo(models.Model):
image = models.ImageField(verbose_name='image')
caption = models.CharField(max_length=128, blank=True, verbose_name='légende')
date_created = models.DateTimeField(auto_now_add=True)
IMAGE_MAX_SIZE = (1900, 1265)
def resize_image(self):
image = Image.open(self.image)
image.thumbnail(self.IMAGE_MAX_SIZE)
image.save(self.image.path)
def save(self, *args, **kwargs):
super().save(*args, **kwargs)
self.resize_image()
def __str__(self):
return self.caption
My models.py
class BlogPost(models.Model):
slug = models.SlugField()
categorie = models.ForeignKey(CategorieBlogs, on_delete=models.CASCADE)
image = models.ForeignKey(Photo, on_delete=models.CASCADE)
title = models.CharField(max_length=500, verbose_name="titre blog")
subtitle = models.CharField(max_length=500, verbose_name="sous titre")
contenu = models.TextField(max_length=1500, verbose_name="contenu blog")
description = models.TextField(max_length=2000, verbose_name="contenu blog 2")
titles = models.CharField(max_length=500, verbose_name="titre 2")
photo = models.ImageField(upload_to="photo blog")
contenus = models.TextField(max_length=2000, verbose_name="paragraph 2", blank=True)
descriptions = models.TextField(max_length=2000, verbose_name="paragraph contenu 2", blank=True)
datepub = models.DateField(verbose_name="Date de publication", auto_now_add=True)
published = models.BooleanField(default=False)
auteur = models.ForeignKey(AuteurPost, on_delete=models.CASCADE)
def save(self, *args, **kwargs):
if not self.slug:
self.slug = slugify(self.title)
super().save(*args, **kwargs)
def get_absolute_url(self):
return reverse("posts:home")
def __str__(self):
return self.title
class Meta:
ordering = ['-datepub']
verbose_name = "Blog"
My views
class BlogHome(ListView):
model = BlogPost
context_object_name = "posts"
template_name = "blog/list.html"
def get_queryset(self):
queryset = super().get_queryset()
if self.request.user.is_authenticated:
return queryset
return queryset.filter(published=True)
class BlogPostDetail(DetailView):
model = BlogPost
context_object_name = "post"
template_name = "blog/detail.html"
My urls.py
from django.urls import path
from .views import BlogHome, BlogPostDetail
app_name = "posts"
urlpatterns = [
path('', BlogHome.as_view(), name="home"),
path('<str:slug>/', BlogPostDetail.as_view(), name="post"),
]
my html code
<header class="masthead" style="background-image: url('{{ post.image.image.url }}')">
<div class="container position-relative px-4 px-lg-5">
<div class="row gx-4 gx-lg-5 justify-content-center">
<div class="col-md-10 col-lg-8 col-xl-7">
<div class="post-heading">
<h1>{{post.title}}</h1>
<h2 class="subheading">{{post.subtitle}}</h2>
<span class="meta">
Publié Par
{{post.auteur }}
le {{ post.datepub}}
</span>
</div>
</div>
</div>
</div>
</header>
<!-- Post Content-->
<article class="mb-4">
<div class="container px-4 px-lg-5">
<div class="row gx-4 gx-lg-5 justify-content-center">
<div class="col-md-10 col-lg-8 col-xl-7">
<p> {{ post.contenu }}</p>
<p> {{ post.description }}</p>
<h2 class="section-heading">{{ post.titles }}</h2> <br> <br>
<img class="img-fluid" src="{{ post.photo.url }}" alt="post.photo" />
<p>{{ post.contenus }}</p>
<p> {{post.descriptions}}</p>
</div>
</div>
</div>
</article>
First of all I think you have not configured your static files and media files. Try configuring it as follows. In your settings.py ensure to include STATICFILES_DIR, STATIC_ROOT, MEDIA_URL, MEDIA_ROOT in your settings.py and then add the below lines below STATIC_URL = 'static/'
MEDIA_URL = 'media/'
STATICFILES_DIRS = [BASE_DIR / 'static']
STATIC_ROOT = BASE_DIR / 'staticfiles/'
MEDIA_ROOT = BASE_DIR / 'static/media'
By doing this you are telling django where to get your static files. now your have to add the link of the static files in your project urls.py. you will add that as below.
from django.conf import settings
from django.conf.urls.static import
static
urlpatterns = [
.......
]
urlpatterns +=
static(settings.STATIC_URL,
document_root=settings.STATIC_ROOT)
urlpatterns += static(settings.MEDIA_URL,
document_root=settings.MEDIA_ROOT
One last thing that I assumed you had done is creating static folder in your project root and inside that static folder create media folder where all the images you want to load are. Now run python manage.py collectstatic

Django not displaying images after adding product details

Django can be able to display the image if I comment out the product details page.
I would like to know why it does that and how can I make it always display the images.
Product model
item_name = models.CharField(max_length=20)
item_description = models.TextField(
max_length=200, verbose_name="Item Description")
item_price = models.FloatField(default=0.00)
slug = models.SlugField(null=True, unique=True)
item_details = models.TextField(
max_length=1000, verbose_name="Item Details")
item_quantity = models.IntegerField(default=0)
item_availability = models.BooleanField(default=False)
is_item_featured = models.BooleanField(default=False)
is_item_recommended = models.BooleanField(default=False)
# Todo: add Is On Carousel Filter
item_brand = models.ForeignKey(Brand, null=True, on_delete=models.CASCADE)
item_categories = models.ForeignKey(
Category, null=True, on_delete=models.CASCADE)
item_image = models.ImageField(upload_to='images/product/',
default="images/product/image-placeholder-500x500.jpg")
Product Views
class HomePageView(ListView):
model = Product
template_name = 'product/index.html'
class ProductListView(ListView):
model = Product
template_name = 'product/product_list.html'
def product_detail(request, slug):
objec = get_object_or_404(Product, slug=slug)
template_name = 'product/product_detail.html'
return render(request, template_name, context={'object': objec})
Product Templates
{% for product in object_list %}
<div class="col-md-3 col-sm-6">
<div class="product-grid4">
<div class="product-image4">
<a href="product/{{ product.slug }}">
<!-- <img src="{{ product.item_brand.brand_image.url }}" alt="{{ product.item_brand.brand_name }}" width="30px"> -->
<img class="pic-1" src="{{ product.item_image.url }}" alt="{{ product.item_name }}">
</a>
<!-- <span class="product-new-label">Recommended</span> -->
<!-- <span class="product-discount-label">-10%</span> -->
</div>
<div class="product-content">
<h3 class="title">{{ product.item_name }}</h3>
<div class="price">
Kshs. {{product.item_price }}
<!-- <span>$16.00</span> -->
</div>
<a class="add-to-cart" href="{% url 'add-to-cart' product.slug %}">ADD TO CART</a>
</div>
</div>
</div>
{% endfor %}
Product Urls
url(r'product/(?P<slug>.+)$', views.product_detail, name='product-detail'),
url('^$', views.HomePageView.as_view(), name='landing_page'),
url('shop/', views.ProductListView.as_view(), name="product-list")
Settings.py
.....
# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/2.0/howto/static-files/
STATIC_ROOT = os.path.join(BASE_DIR, "staticfiles")
STATIC_URL = '/static/'
STATICFILES_DIRS = [
os.path.join(BASE_DIR, "static"),
]
# Simplified static file serving.
# https://warehouse.python.org/project/whitenoise/
STATICFILES_STORAGE = 'whitenoise.storage.CompressedManifestStaticFilesStorage'
MEDIA_URL = '/media/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
The error I get. Please note the error only comes up when product_detail view and it's url are called. When they are commented out, the images are displayed.
Page not found (404)
Request Method: GET
Request URL: http://127.0.0.1:8000/media/images/product/airmax_98_bVXgZPB.jpg
Raised by: shop.views.product_detail
No Product matches the given query.
If you don't want have problems when you change urlpattern, you should replace <a href="product/{{ product.slug }}"> to <a href="{{ product.get_absolute_url }}"> and add a bit of code to models.py
*product fields goes here*
def get_absolute_url(self):
return reverse('product-detail', args=[self.slug])
And don't forget from django.urls import reverse
I've noticed that your django is not pretty new, and if Can not import reverse from django.urls
The problem is with how the url is being displayed.
I should Use path instead of url like so:
Product Urls
......
path('product/<slug>/', views.product_detail, name='product-detail'),
path('shop/', views.ProductListView.as_view(), name="product-list"),
......
I still don't have a clear understanding as to why I should use path instead of url

ValueError at / The 'photo' attribute has no file associated with it

THE PROBLEM :
I want to upload the images of my product file onto the server. But when I am passing the file URL which is
<{{product.photo.url}}> in my HTML file it is displaying value error: photo attribute has no files associated with it.
My python and HTML file code below:
product.py file:
from django.db import models
from django.db.models import ImageField
from .category import Category
class Product(models.Model):
name = models.CharField(max_length=500)
description = models.CharField(max_length=200, blank=True, null=True)
photo = models.ImageField(upload_to='uploads/product/',
blank=True)
category = models.ForeignKey(Category, on_delete=models.CASCADE, default=1)
manufacturer = models.CharField(max_length=300,
blank=True)
price = models.IntegerField(default=0)
#staticmethod
def get_all_products():
return Product.objects.all()
In the above code for Imagefield, I have passed the 'photo' variable but then too the server is displaying error.
urls.py:
from django.contrib import admin
from django.urls import path, include
from django.conf.urls.static import static
from . import settings
urlpatterns = [
path('admin/', admin.site.urls),
path('', include('store.urls'))
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
Index.html code:
<body>
<div.<div class="container-fluid">
<div class="row mx-auto">
{% for product in products %}
<div class="card mx-auto mb-3 mt-3" style="width: 18rem;">
<img src="{{product.photo.url}}" class="card-img-top" alt="...">
<div class="card-body">
<p class="card-title"><b>{{product.name}}</b></p>
<p class="card-text"><b>{{product.price}}</b>
Add To Cart
</div>
</div>
{% endfor %}
</div>
</div>
The confusing thing is when I am passing the code {{product.image.url}} instead of {{product.photo.url}} it is displaying overall output BUT NOT the product image
settings.py code:
STATIC_URL = '/static/'
MEDIA_URL = '/test/'
MEDIA_ROOT = BASE_DIR
I think it is not reading/fetching the URL from source; how should I resolve this?
Your files and code are a bit confusing but this is what I think.
The error
ValueError at / The 'photo'
is pretty clear. The photo has no file/attribute associated with it. I am also unsure as to what you expect this {{product.photo.url} to output — as from what I can see this will yield no value. If you think product refers to the file and photo refers to the defined attribute and url is an indirect variable of the photo object then this is a wrong approach.
See this answer here on how you should go about embedding URL in the src tag - How to add django template variable in img src tag

image is not showing in django templates am new in django and working on a project...i idid lots of rid of this error but nothing happen

am trying to show pic in django tempate but its not working
here is my settings.py where the path of static and media file
STATIC_URL = '/static/'
STATICFILES_DIRS = [ os.path.join(BASE_DIR, 'static'),
]
MEDIA_URL = '/media/'
MEDIA_ROOT = os.path.join(BASE_DIR , "media")
this is my model.py
the image is store under static/img folder
class Loader_post(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE, related_name="Loader")
pick_up_station = models.CharField(max_length=150)
destination_station = models.CharField(max_length=150)
sender_name = models.CharField(max_length=150)
phone_number = PhoneNumberField(null=False, blank=False, unique=True)
receiver_name = models.CharField(max_length=150)
sending_item = models.CharField(max_length=150)
image_of_load = models.ImageField(default='',upload_to='static/img')
weight = models.CharField(max_length=150)
metric_unit = models.CharField(max_length=30, default='')
quantity = models.PositiveIntegerField()
pick_up_time = models.DateField()
drop_time = models.DateField()
paid_by = models.CharField(max_length=150)
created_at = models.DateTimeField(auto_now=True)
published_date = models.DateField(blank=True, null=True)
this is my html template for showing user posted data
{% extends "post.html" %}
{% block content %}
{% load static %}
{% for loader in Loader %}
<h4>Loader Id- {{loader.id}}</h4> Username-{{user.username}}
<h3>Sender name-{{loader.sender_name}}</h3>
</h4>
<p class="card-text">
<h4>pick up station-{{loader.pick_up_station}}</h4>
</p>
<img src="{{ loader.image.url }}" alt="image">
<p class="card-text">{{loader.destination_station}}</p>
<p class="card-text">{{loader.phone_number}}</p>
<p class="card-text">{{loader.receiver_name}}</p>
<p class="card-text">{{loader.sending_item}}</p>
<p class="card-text">{{loader.weight}}</p>
<p class="card-text">{{loader.quantity}}</p>
<p class="card-text">{{loader.pick_up_time}}</p>
<p class="card-text">{{loader.drop_time}}</p>
<p class="card-text">{{loader.paid_by}}</p>
<p class="card-text">{{loader.created_at}}</p>
<a class="btn btn-primary" href="{% url 'Loader:Delete' loader.id %} ">delete</a>
<a class="btn btn-primary" href="{% url 'Loader:Update' loader.id %} ">update</a>
</div> {% endfor %} {% endblock content %}
this is my urls.py
from django.urls import path
from . import views
from django.conf import settings
from django.conf.urls.static import static
app_name = 'Loader'
urlpatterns = [
path('post_detail/', views.Loader_post_view.as_view(), name="post_detail"),
path('post/', views.post.as_view(), name="post"),
path('my_job/', views.Loader_post_list.as_view(), name="my_job"),
path('delete/<int:pk>', views.Loader_post_delete.as_view(), name="Delete"),
path('update/<int:pk>', views.Loader_post_update.as_view(template_name="post_detail.html"), name="Update")
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
how can i remove this error or any bug in my code?
Take a closer look
First of all, you use different names. In the models.py the image attribute corresponds to image_of_load, whereas in your template the src is equal to {{loader.image.url}} not {{loader.image_of_load.url}}. Second, try to put {% load static %} at the very top of your file, which is an advice from the documentation, at least above the {% block content %} tag.
I think that on the models.py file, you should use upload_to='img' because you have set your static folder directory. Remember that the uploaded images by users go to your media folder / URL, not your static folder. The static folder is for CSS files and images that you serve, such as your website's logo.
I hope that helps. Feel free to ask me any more questions!

django broken thumbnails

I am trying to make a blog with an imagefield for my posts. I have imageupload working in the django admin panel but I have broken thumbnails. If I click on the images I got a 404 error with the following:
Using the URLconf defined in firstblog.urls, Django tried these URL patterns, in this order:
^$ [name='home']
^admin/
The current URL, images/heroimage/, didn't match any of these.
in my models.py I have:
from django.db import models
from django.db.models import permalink
class posts(models.Model):
author = models.CharField(max_length = 45)
title = models.CharField(max_length = 100)
bodytext = models.TextField()
timestamp = models.DateTimeField()
image1 = models.ImageField(upload_to="images/heroimage/", default='')
category = models.ForeignKey('blog.Category', default='')
def __unicode__(self):
return '%s' % self.title
#permalink
def get_absolute_url(self):
return ('view_blog_post', None, { 'slug': self.slug })
class Category(models.Model):
title = models.CharField(max_length=100, db_index=True)
slug = models.SlugField(max_length=100, db_index=True)
def __unicode__(self):
return '%s' % self.title
#permalink
def get_absolute_url(self):
return ('view_blog_category', None, { 'slug': self.slug })
What I'm trying to do is to have the image that was uploaded to the post, displayed on the site.
Here is my index.html where I try to call the image to the post.
<div class="container">
<h1>First Blog</h1>
{% for post in posts %}
<div class="posts">
<p> <img src="{{blog.image1.url}}" /> {{ blog }}</p>
<h2>{{ post.title }}</h2>
<h3>Posted on {{ post.timestamp }} by {{ post.author }}</h3>
<p> {{ post.bodytext }}</p>
</div>
<hr>
{% endfor %}
</div>
my django project I created was called firstblog , I then have an app named blog. In the root of my project folder "firstblog" I have a folder for images and then a sub folder inside that one called heroimage.
Can anyone help me get this working?
Thanks
It is appended to your MEDIA_ROOT setting.
https://docs.djangoproject.com/en/1.8/ref/models/fields/#django.db.models.FileField.upload_to
Set a media root for uploaded files the to retrieve the files, ill give you an example:
# settings.py
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
# models
class Blog(models.Model):
main_image = models.ImageField(default='none/none.jpg', upload_to='blog'
# template
<img src="/media/{{ blog.main_image }}">
# media folder after
media/blog/imageuploaded.jpg
media/none/none.jpg # This file was already created
To upload to the static directory change
MEDIA_ROOT = STATIC_ROOT or STATICFILES_DIRS[0]
Though this is absolutely not recommended!

Categories

Resources