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
Related
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
I'm sure i'm obviouly did something very stupid but, when I try to upload my profile picture on my blog website, even when I add one through admin page, the picture doesn't come up..
so here's what's happening,
blog pic:
the picture right next to Kimmc6008, I should see my image, but somehow failed..
here's the code, I will upload more if needed.
models.py
class Author(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
profile_picture = models.ImageField()
def __str__(self):
return self.user.username
class CategoryBlog(models.Model):
title = models.CharField(max_length=20)
def __str__(self):
return self.title
class Post(models.Model):
title = models.CharField(max_length=100)
overview = models.TextField()
timestamp = models.DateTimeField(auto_now_add=True)
comment_count = models.IntegerField(default=0)
author = models.ForeignKey(Author, on_delete=models.CASCADE)
thumbnail = models.ImageField()
categories = models.ManyToManyField(CategoryBlog)
featured = models.BooleanField(null=True)
def __str__(self):
return self.title
views.py
def blog(request):
post_list = Post.objects.all()
context = {
'post_list': post_list
}
return render(request, 'blog.html', context)
and my html
<!-- post -->
{% for post in post_list %}
<div class="post col-xl-6">
<div class="post-thumbnail"><img src="{{post.thumbnail.url}}" alt="..." class="img-fluid"></div>
<div class="post-details">
<div class="post-meta d-flex justify-content-between">
<div class="date meta-last">20 May | 2016</div>
{% for cat in post.categories.all %}
<div class="category">{{ cat }}</div>
{% endfor %}
</div><a href="/post">
<h3 class="h4">{{ post.title }}</h3></a>
<p class="text-muted">{{ post.overview }}</p>
<footer class="post-footer d-flex align-items-center">
<a href="#" class="author d-flex align-items-center flex-wrap">
<div class="avatar"><img src="{{ post.author.profile_picture.url }}" alt="..." class="img-fluid"></div>
<div class="title"><span>{{ post.author.user.username }}</span></div>
</a>
<div class="date"><i class="icon-clock"></i>{{ post.timestamp|timesince }} ago</div>
<div class="comments meta-last"><i class="icon-comment"></i>{{ post.comment_count }}</div>
</footer>
</div>
</div>
{% endfor %}
Thank you for your help!!
EDIT
I noticed I was missing MEDIA_ROOT in my settings.py.
Would this be the reason why?
Add the upload_to argument in your ImageField
profile_picture = models.ImageField(upload_to='pictures')
And these are the basic settings you need to have in your django project for image/files handling
project/urls.py
from django.conf import settings
from django.conf.urls.static import static
urlpatterns = [..]
if settings.DEBUG:
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
settings.py
MEDIA_URL = '/media/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
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">
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!
I'm having issues serving images based on the ImageField in Django.
models.py part looks like that:
class Post(models.Model):
author = models.ForeignKey(Author, on_delete=models.CASCADE)
category = models.ManyToManyField(Category)
trip = models.ForeignKey(Trip, on_delete=models.CASCADE)
main_image = models.ForeignKey(Image, on_delete=models.CASCADE, related_name='main_image')
images = models.ManyToManyField(Image, related_name='images')
class Image(models.Model):
name = models.CharField(max_length=32)
picture = models.ImageField(upload_to='pictures/', blank=True)
trip = models.ForeignKey(Trip, on_delete=models.CASCADE)
taken = models.DateTimeField(blank=True, null=True)
uploaded = models.DateTimeField(default=timezone.now)
def __unicode__(self):
return self.name
settings.py contains the MEDIA_URL and MEDIA_ROOT:
# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/2.1/howto/static-files/
STATIC_URL = '/static/'
STATIC_ROOT = os.path.join(BASE_DIR, 'static')
MEDIA_URL = '/media/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
Also included what I've found in other SO topics in the urls.py:
from django.contrib import admin
from django.urls import path, include
from django.conf.urls import url
from django.contrib.staticfiles.urls import static, staticfiles_urlpatterns
from django.conf import settings
from markdownx import urls as markdownx
urlpatterns = [
path('admin/', admin.site.urls),
path('', include('blog.urls')),
url(r'^markdownx/', include('markdownx.urls')),
] + staticfiles_urlpatterns() + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
In the end I put it in the html template like that:
{% extends 'blog/base.html' %}
{% block leftcolumn %}
{% for post in posts %}
<div class="leftcolumn">
<div class="card" style="max-width: 100%">
<h2>{{ post.title }}</h2>
<h5>published: {{ post.published_date }}, by: {{ post.author }}</h5>
<div><img src="{{ post.main_image.url }}"></div>
<p>{{ post.byline }}</p>
</div>
</div>
{% endfor %}
{% endblock %}
But the image is not shown..
I can see the image if I go to the url host:8000/media/pictures/test_photo.jpgand in general I can display images on the page (e.g. within django-markdownx field) but not through ImageField url.
Any ideas what's wrong here?
This line:
<div><img src="{{ post.main_image.url }}"></div>
should be:
<div><img src="{{ post.main_image.picture.url }}"></div>
The reason is your model Image does not have an url method. The method belongs to the ImageField, in this case picture.