django image uploaded section doesnot shows up in production - django

I tried to upload image from the admin side in production but it doesn't shows up or stores in static/images but it used to work while working in local.
However my static images are loaded and also those I've saved in development are also showing up but while adding new images it doesn't get added to static files.
My model:
class Gallery(models.Model):
title = models.CharField(max_length=150)
image = models.ImageField(upload_to='images/',null=True,default="avatar.svg")
updated = models.DateTimeField(auto_now=True)
created = models.DateTimeField(auto_now_add=True)
def __str__(self):
return self.title
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('base.urls'))
]
urlpatterns +=static(settings.MEDIA_URL,document_root=settings.MEDIA_ROOT)
Gallery .html
{% for gallery in gallerys %}
<!-- ITEM 1 -->
<div class="col-xs-6 col-md-3">
<div class="box-gallery">
<a href="{{gallery.image.url}}" title="Gallery #1">
<img src="{{gallery.image.url}}" alt="" class="img-fluid" />
<div class="project-info">
<div class="project-icon">
<span class="fa fa-search"></span>
</div>
</div>
</a>
</div>
</div>
{% endfor %}
Settings.py
here i've uploaded only the required ones
BASE_DIR = Path(__file__).resolve().parent.parent
STATIC_URL = '/static/'
AUTH_USER_MODEL = 'base.NewUser'
STATIC_ROOT = os.path.join(os.path.dirname(BASE_DIR), "static/")
MEDIA_URL = '/images/'
MEDIA_ROOT = os.path.join(os.path.dirname(BASE_DIR), "/static/images")
DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'
views.py
def gallery(request):
gallerys = Gallery.objects.all()
context = {'gallerys':gallerys}
return render(request, 'base/gallery.html',context)
am i missing something here?
Thanks in advance

The way to store images in static folder.
Do this:
views.py:
def gallery(request):
if request.method == 'POST':
form = YourForm(request.POST, request.FILES)
if form.is_valid():
handle_uploaded_file(request.FILES['image'])
model_instance = form.save()
model_instance.save()
else:
form = YourForm()
gallerys = Gallery.objects.all()
context = {'gallerys':gallerys}
return render(request, 'base/gallery.html',context)
def handle_uploaded_file(f):
with open('static/images/'+f.name, 'wb+') as destination:
for chunk in f.chunks():
destination.write(chunk)
settings.py:
STATIC_URL = 'static/'
STATIC_ROOT=os.path.join(BASE_DIR,'static')
urls.py:
urlpatterns = [
path('admin/', admin.site.urls),
path('', include('base.urls'))
]+static(settings.MEDIA_URL,document_root=settings.MEDIA_ROOT)+static(settings.MEDIA_URL,document_root=settings.MEDIA_ROOT)
This is the way that you can store static files.
I hope this may be get you

Related

Django image does not display

I'm new to Django, and I encounter this problem with images that I can't solve... The path is like this: Django-Project, Profiles, static, media, profileIMG.
Here is my model.
from django.db import models
from accounts.models import NewUser
class UserProfile(models.Model):
user = models.OneToOneField(NewUser, on_delete=models.CASCADE)
profile_pic = models.ImageField(default='Untitled.png', upload_to='profileIMG')
def __str__(self):
return self.user.username
settings.py
STATICFILES_DIRS = [
os.path.join(BASE_DIR, "static"),
]
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
STATIC_URL = '/static/'
MEDIA_URL = '/media/'
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('accounts.urls')),
path('', include('profiles.urls')),
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
form.py
from django.forms import ModelForm
from .models import UserProfile
class ProfileForm(ModelForm):
class Meta:
model = UserProfile
fields = '__all__'
exclude = ['user']
view.py function
#login_required(login_url='login_user')
def profiles(request):
indexID = request.user
form = ProfileForm(instance=indexID)
if request.method == 'POST':
form = ProfileForm(request.POST, request.FILES, instance=indexID)
if form.is_valid():
messages.success(request, ("The file is valid"))
form.save()
else:
messages.success(request, ("Invalid File."))
context = {'form': form}
return render(request, "profiles/profiles.html", context)
And my template profiles.html.
{% load static %}
<div class="main">
<form method="POST" enctype="multipart/form-data">
{% csrf_token %}
<img class="profile-pic" src="{{ request.user.UserProfile.profile_pic.url
}}"/>
<p>This is profile page </p>
<span>Hello, {{request.user}} </span>
<p>{{ form }}</p>
<input class="imgBTN" type="submit" name="imgBTN">
<span>Logout</span>
</form>
</div>
I'm trying to select an image dynamically, not just adding the name of the picture.
Does anyone know how to fix this, please?
in your views all of method is post, nothing get method to get data from database
try add profile = UserProfile.object.get()
and then add context 'profile':profile
so the full view.py like this
#login_required(login_url='login_user')
def profiles(request):
indexID = request.user
profile = UserProfile.object.get(user=indexID)
form = ProfileForm(instance=indexID)
if request.method == 'POST':
form = ProfileForm(request.POST, request.FILES, instance=indexID)
if form.is_valid():
messages.success(request, ("The file is valid"))
form.save()
else:
messages.success(request, ("Invalid File."))
context = {'form': form, 'profile':profile}
return render(request, "profiles/profiles.html", context)
good luck and keep coding

Default profile photo not being displayed

I am working on a twitter clone app and i want users to have a default profile photo when they sign up and login. I have set up the model to upload the default image but for some reason its not displaying.
models.py
from django.db import models
from django.contrib.auth.models import User
#import pylibjpeg_libjpeg
from PIL import Image
# Create your models here.
class Profile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
image = models.ImageField(upload_to='profile_pics', default='default.png')
def __str__(self):
return f'{self.user.username} Profile'
#property
def followers(self):
return Follow.objects.filter(follow_user=self.user).count()
#property
def following(self):
return Follow.objects.filter(user=self.user).count()
def save(self, force_insert=False, force_update=False, using=None, update_fields=None):
super().save()
img = Image.open(self.image.path)
if img.height > 300 or img.width > 300:
output_size = (300, 300)
img.thumbnail(output_size)
img.save(self.image.path)
views.py
#login_required
def profile(request):
if request.method == 'POST':
uform = UserUpdateForm(request.POST, instance=request.user)
pform = ProfileUpdateForm(request.POST, request.FILES, instance=request.user.profile)
if uform.is_valid() and pform.is_valid():
uform.save()
pform.save()
messages.success(request, f'Account updated.')
return redirect('profile')
else:
uform = UserUpdateForm(instance=request.user)
pform = ProfileUpdateForm(instance=request.user.profile)
return render(request, 'Users/profile.html', {'uform': uform, 'pform': pform})
settings file
STATIC_URL = '/static/'
STATIC_ROOT = os.path.join(BASE_DIR, "staticfiles")
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
MEDIA_URL = '/media/'
html file
<article class="media content-section" style="height:140px; width:100%">
{% if user_profile != None %}
<div class="mt-2 d-flex full-width align-items-center">
<img class="rounded-circle mr-3 img-fluid" style="width:90px; height:90px" src="{{ user_profile.profile.image.url }}">
<div>
<h4 style="text-align: left" class="white-important">
{{ user_profile.username}}
</h4>
<h6 style="text-align:left" class="email-profile">
{{ user.email }}
</h6>
</div>
</div>
{% else %}
<div class="mt-2 d-flex full-width align-items-center">
<img class="rounded-circle mr-3" style="width:90px; height:90px;" src="{{ user.profile.image.url }}" alt="profile picture">
<div>
<h4 style="text-align: left" class="white-important">
{{ user.username }}
</h4>
<h6 style="text-align:left" class="email-profile">
{{ user.email }}
</h6>
</div>
</div>
{% endif %}
my project's urls.py file
from django.contrib import admin
from django.urls import path, include
from django.contrib.auth import views as auth_views
from django.conf import settings
from django.conf.urls.static import static
from Users import views as users_views
urlpatterns = [
path('admin/', admin.site.urls),
path('login/', auth_views.LoginView.as_view(template_name='Users/login.html'), name='login'),
path('logout/', auth_views.LogoutView.as_view(template_name='Users/logout.html'), name='logout'),
path('password-reset/', auth_views.PasswordResetView.as_view(template_name='Users/password_reset.html'),name='password-reset'),
path('password-reset/done', auth_views.PasswordResetDoneView.as_view(template_name='Users/password_reset_done.html'), name='password-reset-done'),
path('password-reset/confirm/<uid64>/<token>/', auth_views.PasswordResetConfirmView.as_view(template_name='Users/password_reset_confirm.html'), name='password-reset-done'),
path('register/', users_views.register, name='register-users'),
path('profile/', users_views.profile, name='profile'),
path('search/', users_views.SearchView, name='search'),
path('', include("Blog.urls")),
]
if settings.DEBUG is True:
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
here's the screenshot of the output after the user logs in
It seems like you are not serving the media files locally. Check the documentation here
inspect the image on your browser and see what is being rendered. also, try adding a trailing slash to the media_root such that it is MEDIA_ROOT = os.path.join(BASE_DIR, 'media/')
In views.py check the indentation of pform.save() ...
if still not working follow/check these steps :
settings.py:
STATIC_DIR = os.path.join(BASE_DIR,"static")
MEDIA_DIR = os.path.join(BASE_DIR, 'media')
# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/3.1/howto/static-files/
STATIC_URL = '/static/'
STATICFILES_DIRS = [
STATIC_DIR,
]
#MEDIA
MEDIA_ROOT = MEDIA_DIR
MEDIA_URL = '/media/'
LOGIN_URL = 'user_login'
create a folder named media with a subfolder profile_pics in your base directory (the folder where you have your manage.py file)
also check this similar code :
models.py :
from django.db import models
from django.contrib.auth.models import User
# Create your models here.
class user_profile(models.Model):
#using default User model by linking
user = models.OneToOneField(User, on_delete=models.CASCADE)
#additional fields
website = models.URLField(blank=True)
profile_picture = models.ImageField(upload_to='profile_pictures' , blank = True )
bio = models.CharField(blank=True, max_length=300)
def __str__(self):
return self.user.username
forms.py:
from django import forms
from django.contrib.auth.models import User
from .models import user_profile
class User_form(forms.ModelForm):
password = forms.CharField(widget=forms.PasswordInput())
class Meta:
model = User
fields = ("username", "email" , "password")
class user_profile_form(forms.ModelForm):
class Meta:
model = user_profile
fields = ("profile_picture", "website" , "bio")
views.py :
def signup(request):
registered = False
if request.method == "POST":
user_form = User_form(data=request.POST)
user_profileform = user_profile_form(data=request.POST)
if(user_form.is_valid() and user_profileform.is_valid()):
user = user_form.save()
user.set_password(user.password)
user.save()
profile = user_profileform.save(commit=False)
profile.user = user
if 'profile_picture' in request.FILES:
profile.profile_picture = request.FILES['profile_picture']
profile.save()
registered = True
else:
print(user_form.errors, user_profileform.errors)
else:
user_form = User_form()
user_profileform = user_profile_form()
return render(request, "registration/signup.html", {'user_form': user_form , 'user_profileform' : user_profileform, 'registered' : registered } )
Also make sure your template form has the "multipart/form-data":
signup.html :
<form enctype="multipart/form-data" method="POST">
<div class="container sign-form">
{% csrf_token %}
{{ user_form |as_bootstrap }}
{{ user_profileform |as_bootstrap }}
<!-- {{ user_profileform.as_p }} -->
<input type="submit" class = “btn btn-default” name="submit" value="submit">
also check if you are rendering the image in the template properly . something like this ,
<div class="container">
<img src="media/{{[context_object_name].image}}" class="imgbar" id="img">
</div>
even now not solved, open the browser console and let know what is the error displayed
edit :
add this[+ static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)] to your urls.py,
urls.py:
from django.urls import path,include
from . import views
from django.conf import settings
from django.conf.urls.static import static
app_name = 'homepage'
urlpatterns = [
path('', views.home , name = "home"),
path('contact', views.contact , name = "contact"),
path('about', views.about , name = "about"),
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)

Photo not displaying in django html

I spent a few hours trying to find out what is going on but I can`t see why the photo is not displayed in my html file.
Goal: Display the profile photo of each user
Issue: Photo not displaying in django html
detail.html
<div class="col-sx-1 col-sm-5 text-right">
<a href="{% url 'contacts:detail' contact.id %}">
{% if contact.photo %}
<img src="/{{ contact.photo.url }}" class="img-responsive">
{% else %}
<h3>No image to display</h3>
{% endif %}
</a>
</div>
views.py
def create_contact(request):
form = ContactForm(request.POST or None, request.FILES or None)
if form.is_valid():
contact = form.save(commit=False)
contact.user = request.user
contact.photo = request.FILES['photo']
file_type = contact.photo.url.split('.')[-1]
file_type = file_type.lower()
if file_type not in IMAGE_FILE_TYPES:
context = {
'contact': contact,
'form': form,
'error_message': 'Image file must be PNG, JPG, or JPEG',
}
return render(request, 'contacts/create_contact.html', context)
contact.save()
return render(request, 'contacts/detail.html', {'contact': contact})
context = {
'form': form,
}
return render(request, 'contacts/create_contact.html', context)
urls.py
urlpatterns = [...]
urlpatterns += static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
models.py
class Contact(models.Model):
photo = models.ImageField(upload_to='profileimage', blank = True)
settings.py
STATIC_URL = '/static/'
MEDIA_URL = '/media/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
Many Thanks,
I have resolved this issue by adding static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT) to the main urls.py file. I hope this help.

How to serve media files with Django in local environment?

I have a problem when trying to display in a template a picture from my media file (for example a profil picture from an user). I have already looked at many topics, and everytime the answer is simply adding the line urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT) in the urls.py file. But I already have it and it still doesn't work. Here are the relevant part of my files :
urls.py
from django.contrib import admin
from django.urls import path, include
from django.conf.urls.static import static
from django.conf import settings
urlpatterns = [
path('admin/', admin.site.urls),
path('', include('actualites.urls')),
path('inscription/', include('inscription.urls')),
]
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
settings.py
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
MEDIA_ROOT = os.path.join(BASE_DIR, 'media/')
MEDIA_URL = '/media/'
STATIC_URL = '/static/'
STATICFILES_DIRS = (
os.path.join(BASE_DIR, "static"),
)
views.py
def home(request):
return render(request, 'actualites/home.html', {'last_meals': Plat.objects.all()})
models.py
class Plat(models.Model):
titre = models.CharField(max_length = 100)
date = models.DateField(default=timezone.now, verbose_name="Date de préparation")
photo = models.ImageField(upload_to = "photos_plat/", blank = True)
class Meta:
verbose_name = "Plat"
ordering = ['date']
def __str__(self):
return self.titre
You can see that the pictures are recorded in the photos_plat directory, which is a subdirectory of the media directory.
the template :
{% extends "base.html" %}
{% block content %}
<h2>Bienvenue !</h2>
<p>
Voici la liste des plats disponibles :
</p>
{% for meal in last_meals %}
<div class="meal">
<h3>{{ meal.title }}</h3>
<img src="{{ meal.photo.url }}" height=512 width=512/>
<p>{{ meal.description|truncatewords_html:10 }}</p>
<p>Afficher le plat</p>
</div>
{% empty %}
<p>Aucun plat disponible.</p>
{% endfor %}
{% endblock %}
When I go the home page, I get the following error : ValueError at /
The 'photo' attribute has no file associated with it.
I have tried moving the pictures from the "photos_plat" directory directly to the media directory but that changes nothing.
I don't know what I did wrong, can someone help me please ?
Thanks in advance !

Django does not see the static files images

I'm trying to create an online store with Django. I want to add photos of goods, but Django for some reason does not see them. Please help to solve the problem.
Here is a screenshot of error:
here is settings.py
BASE_DIR = os.path.dirname(os.path.abspath(__file__))
STATIC_ROOT = 'staticfiles'
STATICFILES_DIRS = (
os.path.join(BASE_DIR, 'static'),
'../static/products/media/product_images/',
)
models.py
from django.db import models
# Create your models here.
class Product(models.Model):
name = models.CharField(max_length=70, blank=True, null=True, default=None)
price = models.DecimalField(max_digits=10, decimal_places=2, default=0)
description = models.TextField(blank=True, null=True, default=None)
short_description = models.TextField(blank=True, null=True, default=None)
is_active = models.BooleanField(default=True)
created = models.DateTimeField(auto_now_add=True, auto_now=False)
updated = models.DateTimeField(auto_now_add=False, auto_now=True)
def __str__(self):
return "%s, %s" % (self.price ,self.name)
class Meta:
verbose_name = 'Товар'
verbose_name_plural = 'Товары'
class ProductImage(models.Model):
product = models.ForeignKey(Product, blank=True, null=True, default=None, on_delete=models.CASCADE)
image = models.ImageField(upload_to='static/media/product_images/')
is_active = models.BooleanField(default=False)
is_main = models.BooleanField(default=True)
created = models.DateTimeField(auto_now_add=True, auto_now=False)
updated = models.DateTimeField(auto_now_add=False, auto_now=True)
def __str__(self):
return "%s" % self.id
class Meta:
verbose_name = 'Фотография'
verbose_name_plural = 'Фотографии'
main urls.py file
from django.contrib import admin
from django.urls import include, path
from django.conf import settings
from django.conf.urls.static import static
urlpatterns = [
path('admin/', admin.site.urls),
path('', include('online_shop.urls', namespace='online_shop')),
path('', include('products.urls', namespace='products')),
path('', include('orders.urls', namespace='orders')),
]
html template
{% extends 'online_shop/base.html' %}
{% load static %}
{% block content %}
<section>
<div class="top-section">
<img src="{% static 'img/clem.png' %}" class="img-fluid">
</div>
</section>
<section>
<div class="container">
<div class="row">
{% for product_image in product_images %}
<div class="col-lg-3">
<div class="product-item">
<div>
<img src="{{product_image.image}}" alt="" class="img-fluid">
</div>
<h4>{{product_image.product.name}}</h4>
<p>{{product_image.product.description|truncatechars_html:80 }}</p>
<div class="price">
{{product_image.product.price}} ГРН
</div>
<div class="add-to-card">
<button class="btn btn-success">
Добавить в корзину
</button>
</div>
</div>
</div>
{% endfor %}
</div>
</div>
</section>
{% endblock content %}
You may need to do some modifications
settings.py
# prefix used in static files path rendering
STATIC_URL = '/static/'
# store static files once execute python manage.py collectstatic
STATIC_ROOT = os.path.join(BASE_DIR, 'staticfiles/')
# directories where static files are stored in the development environment
STATICFILES_DIRS = [
os.path.join(BASE_DIR, "static"),
]
# prefix used upon uploaded images
MEDIA_URL = '/media/'
# where uploaded images should save
MEDIA_ROOT = os.path.join(BASE_DIR, 'media/')
urls.py
# lets you have the ability to view images even in development environment
if settings.DEBUG:
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
update:
Since you use static/media/product_images/ as upload path, the uploaded files will be saved in
project-root-dir/media/static/products/media/product_images
Hope this helps!
you can do this by adding the following snippet to your urls.py
from django.contrib import admin
from django.urls import include, path
from django.conf import settings
from django.conf.urls.static import static
urlpatterns = [
path('admin/', admin.site.urls),
path('', include('online_shop.urls', namespace='online_shop')),
path('', include('products.urls', namespace='products')),
path('', include('orders.urls', namespace='orders')),
] + static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)