Django: blog image not uploading properly - python

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')

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

Output is not rendered on Django template for the same model whose output is rendered on another template

I am really new to Django and I am building a website while learning it. As per requirements, I have to show some news articles on both the home page and on another page that I navigate from the navbar. I have shown the articles list and individual details with the loop in my template files. Problem is, although I have written the for loop for rendering the news article on the home page, nothing is showing up. Following are my models.py, views.py, app/urls.py, and project/urls.py files :
#models.py
from django.contrib.auth.models import User
from django.db import models
from django.urls import reverse
from django.utils import timezone
from django.utils.translation import gettext_lazy as _
from taggit.managers import TaggableManager
from ckeditor.fields import RichTextField
class Post(models.Model):
STATUS_CHOICES = (
('draft', 'Draft'),
('published', 'Published'),
)
title = models.CharField(max_length=250)
# slug = models.SlugField(max_length=250, unique_for_date='publish')
slug = models.CharField(_("Slug"), max_length=200)
author = models.ForeignKey(User, on_delete=models.CASCADE, related_name='blog_posts')
body = RichTextField()
# image_header = models.ImageField(unique=True, default=timezone.now)
publish = models.DateTimeField(default=timezone.now)
# created = models.DateTimeField(auto_now_add=True)
# updated = models.DateTimeField(auto_now=True)
status = models.CharField(max_length=10, choices=STATUS_CHOICES, default='draft')
class Meta:
ordering = ('-publish',)
def __str__(self):
return self.title
def get_absolute_url(self):
return reverse('blog:details', args=[self.slug])
class News(models.Model):
STATUS_CHOICES = (
('draft', 'Draft'),
('published', 'Published'),
)
news_title = models.CharField(max_length=250) unique_for_date='nw_publish', unique=True, null=True)
slug = models.SlugField(max_length=300, unique_for_date='nw_publish')
news_author = models.ForeignKey(User, on_delete=models.CASCADE, related_name='news_posts')
news_body = RichTextField()
image_header = models.ImageField(upload_to='featured_image/%Y/%m/%d/', null=True, blank=True)
nw_publish = models.DateTimeField(default=timezone.now)
nw_status = models.CharField(max_length=10, choices=STATUS_CHOICES, default='draft')
news_tags = TaggableManager()
class Meta:
ordering = ('nw_publish',)
def __str__(self):
return self.news_title
def get_absolute_url(self):
return reverse('news:news_detail', args=[self.slug])
#views.py
from django.views import generic
from django.views.generic import ListView, DetailView
from django.http import Http404
from .models import Post, Report, News, Member, Project
class Home(ListView):
model = Post
context_object_name = 'home'
template_name = 'blog/home.html'
class HomeDetail(generic.DetailView):
model = Post
context_object_name = 'details'
template_name = 'blog/details.html'
class NewsListView(ListView):
model = News
context_object_name = 'newss'
template_name = 'blog/news.html'
class NewsDetailView(DetailView):
model = News
context_object_name = 'news'
template_name = 'blog/news_detail.html'
#app/urls.py
from django.urls import path, re_path
from . import views
from .views import Home, HomeDetail, Contact, ReportListView, ReportDetailView, NewsListView, NewsDetailView
app_name = 'blog'
urlpatterns = [
# post views
path('', Home.as_view(), name='home'),
path('home/<slug:slug>/', HomeDetail.as_view(), name='details'),
path('news/', NewsListView.as_view(), name='news_list'),
path('news/<slug:slug>/', NewsDetailView.as_view(), name='news_detail'),
path('contact/', Contact.as_view(), name='contact'),
]
#project/urls.py
from django.conf import settings
from django.conf.urls.static import static
from django.contrib import admin
from django.urls import path, include
urlpatterns = [
path('admin/', admin.site.urls),
path('', include('blog.urls', namespace='blog')),
path('ckeditor/', include('ckeditor_uploader.urls')),
path('members/', include('blog.urls', namespace='members')),
path('news/', include('blog.urls', namespace='news')),
path('contact/', include('blog.urls', namespace='contact')),
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
Now my template file for new list has the following block of codes and the objects are rendered :
<div class="row">
{% for news in newss %}
<div class="col-lg-4 wow fadeInUp" data-wow-delay="100ms">
<!--News Two Single-->
<div class="news-two__single">
<div class="news-two__img-box">
<div class="news-two__img">
{% if news.image_header %}
<img src={{ news.image_header.url }} alt="{{ news.news_title }}">
{% endif %}
<a href={{ news.get_absolute_url }}>
<i class="fa fa-plus"></i>
</a>
</div>
<div class="news-two__date">
<p>{{ news.nw_publish |date:"M d, Y" }}</p>
</div>
</div>
<div class="news-two__content">
<ul class="list-unstyled news-two__meta">
<li><i class="far fa-user-circle"></i> {{ news.news_author }}</li>
</ul>
<h3>
<a href={{ news.get_absolute_url }}>{{ news.news_title }}</a>
</h3>
<p class="news-two__text">{{ news.news_body | truncatechars:110 | safe }}</p>
</div>
</div>
</div>
{% endfor %}
</div>
On my home page, I need to achieve something like the following:
news page
I added the following code to render the object, but it's blank:
<div class="row">
<div class="col-xl-6 col-lg-6">
{% for news in newss %}
<div class="news-one__left">
<div class="news-one__img">
<img src={% static "assets/images/blog/news-one-img-1.jpg" %} alt="">
<a href="{{news.get_absolute_url}}">
<i class="fa fa-plus"></i>
</a>
</div>
<div class="news-one__bottom">
<ul class="list-unstyled news-one__meta">
<li>20 Jan, 2021</li>
<li><span>/</span></li>
</ul>
<h3 class="news-one__title">
{{ news.news_title }}
</h3>
</div>
</div>
{% endfor %}
</div>
</div>
The output looks like this:
homepage
My Django version is 3.27.2 and my python version is 3.6.8.
Sorry for such a silly question. I am trying to achieve:
All the news articles both on the home page and news page as a list
Show the first news in the left box and the rest of the 3 or 4 news in the right side box
But the output of the loop is not visible as per the attached image. Please point me to what I am doing wrong here. I am stuck for a while. Thanks in advance.

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

How Do I Get Django to Show Image Field From Model in Templates?

I am trying to get the uploaded image to show in the project template. Here is what my code looks like currently:
projects.html
{% extends "base.html" %}
{% block content %}
<h1>{{ project.title }} HELLO</h1>
<div class="content-section">
<div class="media">
<img src="{{ project.image.url }}" alt="beach" width=250px height=250px />
</div>
<div>
<h5>About the project:</h5>
<p>{{ project.description }}</p>
<br>
<h5>Technology used:</h5>
<p>{{ project.tools }}</p>
</div>
</div>
{% endblock content %}
models.py
class Project(models.Model):
title = models.CharField(max_length=500, unique=True)
description = models.TextField(max_length=500)
tools = models.CharField(max_length=200)
image = models.ImageField(default='default.jpg', upload_to="beach_photos", blank=True)
def __str__(self):
return f'{self.title}'
views.py
from django.shortcuts import render
from django.http import HttpResponse
from projects.models import Project
def projects(request):
project = {
'project':Project.objects.all()
}
return render(request, 'projects/projects.html', context = project)
settings.py configuration (app is installed)
STATIC_URL = 'static/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
MEDIA_URL = '/media/'
When I inspect the image element in the webpage, the source shows up as
src=""
None of the other calls to the model are appearing either.
Any help would be appreciated.
i think you forgot to add a for-loop in your template. try this:
{% for p in project %}
{{ p.title %}}
{% endfor %}
Make sure that the image field of your record in the database is full.
Access the required model with the python manage.py shell command and check if this model has a value of variable.image.url.

Upload an image and display it on a webpage with Django

I'm new at Django and I've been following the django tutorial "djangogirl" but i wanted to add pictures so I did a model.py like this:
class Post(models.Model):
author = models.ForeignKey('auth.User')
image = models.ImageField()
title = models.CharField(max_length=200)
text = models.TextField()
created_date = models.DateTimeField(default=timezone.now)
published_date = models.DateTimeField(blank=True, null=True)
def publish(self):
self.published_date = timezone.now()
self.save()
def __str__(self):
return self.title
This is my view.py:
def posts(request):
posts = Post.objects.order_by('published_date')
return render(request, 'my_blog/posts.html', {'posts': posts})
And my_blog.html:
{% extends 'my_blog/base.html' %}
{% load staticfiles %}
{% block content %}
<link rel="stylesheet" href="{% static 'style/css/posts.css' %}">
<div id="postsContainer">
<div id="posts">
{% for post in posts %}
<div>
<h3 class="date">Published the: {{ post.published_date }}</h3>
<h1>{{ post.title }}</h1>
<img src="{{ post.image.url }}"/>
<p>{{ post.text|linebreaks }}</p>
</div>
<div id="button">
<button type="button" class="btn btn-primary">Read more</button>
</div>
<div class="top-divider"></div>
{% endfor %}
</div>
</div>
{% endblock %}
And I insert my image via the Django admin page.
The problem is the URL that is returned in my HTML is really weird like: ./images_SseHlrA.png and it doesn't obviously display the picture correctly. How can I fixed it?
Apparently the picture are 'stocked' at the root level (same level than the file manage.py the question is why? and how can I change it and what is the best way to do so?
alix is right that "You need to specify where to store images uploaded by user" by specifying upload_to in the field constructor. But you don't need a special class to handle all of this. Way too complicated. Let's say you have this in your settings:
MEDIA_ROOT = os.path.join(BASE_DIR, 'uploads')
MEDIA_URL = '/uploads/'
In your template, you should now be able to do something like:
<img src="{{ post.image.url }}">
You need to specify where to store images uploaded by user. Try this in your models.py:
from django.utils.deconstruct import deconstructible
#deconstructible
class PathAndRename(object):
def __init__(self, sub_path):
self.path = sub_path
def __call__(self, instance, filename):
ext = filename.split('.')[-1]
# set filename as random string. change here as you want
filename = '{}.{}'.format(uuid4().hex, ext)
# return file path
return os.path.join(self.path, filename)
path_and_rename = PathAndRename("/images")
And then in model:
image = models.ImageField(upload_to=path_and_rename)
You can read more about ImageField here and here

Categories

Resources