I can redirect to uploaded image through admin-panel but I can't load it on page. In HTML source code it looks like this:
<img src="" height = "200" with = "200" />
So here's my code:
models.py:
class Profile(models.Model):
user = models.ForeignKey(User)
avatar = models.ImageField(upload_to='images/users/', verbose_name='Аватар', default = 'images/users/ava.gif/')
urls.py:
from django.conf.urls import url, include
from django.contrib import admin
from django.conf import settings
from django.conf.urls.static import static
from django.contrib.staticfiles.urls import staticfiles_urlpatterns
from mainpage.views import *
urlpatterns = [
#other urls
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT) + staticfiles_urlpatterns()
settings.py:
MEDIA_ROOT = 'C:/<<path to django app dir>>/media'
MEDIA_URL = '/media/'
template:
{% block content %}
<body>
<h1>{{ user.username }}</h1>
<img src="{{ MEDIA_URL }}{{ profile.avatar.url }}" height = "200" with = "200" />
<p>
<ul>
<li>email: {{ user.email }}</li>
</ul>
</p>
</body>
{% endblock %}
Will be very thankful for any help.
First thing to do is check the HTML generated by your code.
I don't think you need the {{ MEDIA_URL }} as profile.avatar.url should include the full url if you have your media settings correct.
<img src="{{ profile.avatar.url }}" height = "200" with = "200" />
Related
I am trying to build an e-commerce website using python's Django framework as part of a practice project. However, I am not being able to display my product's image on my landing page.
Django version: 3.2.4
models.py:
class Listing(models.Model):
title = models.CharField(max_length=100)
price = models.FloatField()
description = models.TextField()
image = models.ImageField(upload_to="auctions/images/", default="")
settings.py:
STATIC_URL = '/static/'
# Managing media
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
MEDIA_URL = '/media/'
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("auctions.urls"))
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
views.py
def index(request):
listings = Listing.objects.all()
return render(request, 'auctions/index.html', {
"listings": listings
})
index.html
{% extends "auctions/layout.html" %}
{% load static %}
{% block body %}
<h2>Active Listings</h2>
{% for listing in listings %}
<div class="card" style="width: 18rem;">
<img class="card-img-top" src="{% static listing.image %}" alt="Card image cap">
<div class="card-body">
<h5 class="card-title">{{ listing.title }}</h5>
<p class="card-text">{{ listing.description }}</p>
<p class="card-text">Price - {{ listing.price }}</p>
Bid
</div>
</div>
{% endfor %}
{% endblock %}
I am only getting the alt attribute for the img tag.
As mentioned by #Pruthvi Barot you need to change the code you are using in your html from
src="{% static listing.image %}"
to
src="{% url listing.image.url %}"
That is because you image as a media and allowing them to served via a url as you define here:
# Managing media
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
MEDIA_URL = '/media/'
The static file are in this case images that you placed in the directory and do not manage (upload and delete) from the Django Admin Panel.
another solution mentioned by #MojixCoder is to replace the above mention line of code with
src="{{ listing.image.url }}"
This is the preferred solution and is the one specified in Djangos official documentation on MEDIA_URL (version 3.2)
I am new to django and I am trying to build web site for my friend how makes handmade lamps.
My problem is that I have 3 different models that contains different types of lamps, and I want to get access to certain picture in any of this 3 models and display a picture and description on the other page,but it shows only some pictures from first model and for others throws an error.
this is my html and views.py codes.
{% for q in project1.reverse|slice:":2"%}
<div class="image-selected__lamps">
<a href="{% url 'project_detail' q.pk%}">
<img src="{{q.image.url }}">
</a>
</div>
{%endfor%}
{% for e in project2.reverse|slice:":2"%}
<div class="image-selected__lamps">
<a href="{% url 'project_detail' e.pk %}">
<img src="{{e.image.url}}">
</a>
</div>
{%endfor%}
{% for s in project3.reverse|slice:":2"%}
<div class="image-selected__lamps">
<a href="{% url 'project_detail' s.pk %}">
<img src="{{s.image.url}}">
</a>
</div>
{%endfor%}
enter image description here
def project_detail(request, pk):
project = (LampType1.objects.get(pk=pk), LampType2.objects.get(pk=pk), LampType3.objects.get(pk=pk))
context = {
'project': project,
}
return render(request, 'project_detail.html', context)
Edward this might be happening because you are passing the same id/pk to all the models and you got a picture from the first model and not from the other because an object with that id/pk does not exit in the other models.
To check, register your models in the admin and check weather an object with that particular id exit or not.
check if these steps have been done
model
class LampType1(models.Model):
title = models.CharField(max_length=40)
description = models.TextField()
image = models.ImageField(upload_to='media')
#not
#image = ImageField(upload_to='media')
settings.py
MEDIA_URL = 'media/'
MEDIA_ROOT = Path.joinpath(BASE_DIR,'media')
urls.py
from django.conf.urls.static import static
from django.conf import setting
urlpatterns = [.....
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
from django.contrib import admin
html
{% for p in project %}
<img src="{{ p.image.url }}">
{% endfor %}
I'm using an inlineformset so that a user can upload multiple images at once. The images are saved and functionality is as expected, except on the front-end side. When I loop through my formset with a method resembling {{ form. image }}, I can clearly see that my image is saved and when I click the url, I am redirected to the uploaded file. The problem seems to be that the absoulte url is not stored when I try to set the image's URL as a src for an image element.
Trying to log MEDIA_URL and MEDIA_ROOT in a <p> tag yields no results.
settings.py
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
MEDIA_URL = '/media/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
ROOT_URLCONF = 'dashboard_app.urls'
STATIC_URL = '/static/'
STATICFILES_DIRS = [
os.path.join(BASE_DIR, 'static'),
]
urls.py
from django.conf.urls import url, include
from . import views
from django.conf.urls.static import static
from django.conf import settings
app_name = 'Accounts_Namespace'
urlpatterns = [
url(r'^$', views.Register, name='Accounts_Register'),
url(r'^change-password/$', views.ChangePassword, name="Accounts_Change_Password"),
url(r'^login/$', views.Login, name='Accounts_Login'),
url(r'^logout/$', views.Logout, name='Accounts_Logout'),
url(r'^profile/$', views.ViewProfile, name='Accounts_View_Profile'),
url(r'^profile/edit/$', views.EditProfile, name="Accounts_Edit_Profile"),
url(r'^school/', include('student_map_app.urls', namespace="Student_Maps_Namespace")),
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
models.py
class Gallery(models.Model):
id = models.AutoField(primary_key=True)
user = models.ForeignKey(get_user_model(), on_delete=models.CASCADE)
image = models.ImageField(upload_to="gallery_images")
uploaded = models.DateTimeField(auto_now_add=True)
views.py
def EditProfile(request):
user = request.user
galleryInlineFormSet = inlineformset_factory(get_user_model(), Gallery, form=GalleryForm)
selectedUserGallery = Gallery.objects.filter(user=user).order_by('uploaded')
userGallery_initial = [{'image': selection.image} for selection in selectedUserGallery] # Using this syntax because formset initials accept dictionaries
if request.method == "POST":
profile_form = ProfileEditForm(request.POST, instance=request.user)
gallery_inlineformset = galleryInlineFormSet(request.POST, request.FILES) # Essentially, we're passing a queryset
if profile_form.is_valid() and gallery_inlineformset.is_valid():
# Altering the User model through the UserProfile model's UserProfileForm representative
user.first_name = profile_form.cleaned_data['first_name']
user.last_name = profile_form.cleaned_data['last_name']
user.save()
new_images = []
for gallery_form in gallery_inlineformset:
image = gallery_form.cleaned_data.get('image')
if image:
new_images.append(Gallery(user=user, image=image))
try:
Gallery.objects.filter(user=user).delete()
Gallery.objects.bulk_create(new_images)
messages.success(request, 'You have updated your profile.')
except IntegrityError:
messages.error(request, 'There was an error saving your profile.')
return HttpResponseRedirect('https://www.youtube.com')
else:
profile_form = ProfileEditForm(request.user)
gallery_inlineformset = galleryInlineFormSet(initial=userGallery_initial)
args = { 'profile_form':profile_form, 'gallery_inlineformset':gallery_inlineformset }
return render(request, 'accounts_app/editprofile.html', args)
editprofile.html
{% block main %}
<section class="Container">
<section class="Main-Content">
<form id="post_form" method="POST" action='' enctype='multipart/form-data'>
{% csrf_token %}
{{ gallery_inlineformset.management_form }}
{% for gallery_form in gallery_inlineformset %}
<div class="link-formset">
{{ gallery_form.image }} <!-- Show the image upload field -->
<p>{{ MEDIA_ROOT }}</p>
<p>{{ MEDIA_URL }}</p>
<img src="/media/{{gallery_form.image.image.url}}">
</div>
{% endfor %}
<input type="submit" name="submit" value="Submit" />
</form>
</section>
</section>
{% endblock %}
Again, when I try:
<img src="{{ MEDIA_URL }}{{ gallery_form.image.url }}">
I get a value of "unknown" as the source, but I can click the link that "{{ gallery_form.image}}" generates and see the image that was uploaded. Trying to log both "MEDIA_URL" and "MEDIA_ROOT" yields no results. Not quite sure where the issue lies.
Use <img src="{{ gallery_form.image.url }}"> and make sure image is not None
add this line in your urls.py
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
No need to add {{MEDIA_URL}} before address of your image. because by default it will add /media before your image url path.
Also be sure to add all path starting media to your urls.
from django.conf import settings
if settings.DEBUG:
urlpatterns += patterns('',
(r'^media/(?P<path>.*)$', 'django.views.static.serve', {
'document_root': settings.MEDIA_ROOT}))
also when trying to print an image url in django template, handle situations that image not exist like this:
<img src="{% if gallery_form.image %}{{ gallery_form.image.url }}{%else%} <default-image-path-here> {%endif%}"
While I didn't figure out why I couldn't use the .url() method Django has predefined, I did however, end up using another solution suggested to me by a user in a previous question of mine. Basically, after a user has uploaded images and we have them stored in a database, we make a variable storing the URL attribute of those images, and access that variable from the template. It looks something like this:
views.py
selectedUserGallery = Gallery.objects.filter(user=user) # Get gallery objects where user is request.user
userGallery_initial = [{'image': selection.image, 'image_url':selection.image.url} for selection in selectedUserGallery if selection.image]
if request.method == "GET":
print("--------GET REQUEST: PRESENTING PRE-EXISTING GALLERY IMAGES.-------")
profile_form = ProfileEditForm(request.user)
gallery_inlineformset = galleryInlineFormSet(initial=userGallery_initial)
template.html
<form id="post_form" method="POST" action='' enctype='multipart/form-data'>
{% csrf_token %}
{{ gallery_inlineformset.management_form }}
{% for gallery_form in gallery_inlineformset %}
<div class="link-formset">
{{ gallery_form.image }} <!-- Show the image upload field, this is not he image var from views.py -->
{% if gallery_form.image is not None %}
<p>The image should be below:</p>
<img src="{{ gallery_form.initial.image_url }}">
{% endif %}
</div>
{% endfor %}
<input type="submit" name="gallery-submit" value="Submit" />
</form>
Also, I ended up replacing most of code from the original post as I'm no longer using bulk_create().
I trying to open content inside poster using a dynamic url, but I am facing a problem
my code is for a simple web page containing some movie posters and when I click on a poster new template on a new page should open which will show information about this poster.
but whenever I click on a poster same template(index.html) opens in a new page instead of page.html
eg
127.0.0.1:8000/home is web page with all posters and I clicked on poster1 with id=1 then in new page 127.0.0.1/home/1 will open but it is still index.html with all posters, not page.html in which content of poster1 id=1 is stored.
Here is my code
homepage/models.py
from django.db import models
class Poster(models.Model):
poster_name = models.CharField(max_length=20)
poster_img = models.FileField(upload_to="poster_image/")
def __str__(self):
return self.poster_name
class Poster_page(models.Model):
poster = models.ForeignKey(Poster, default= 1)
poster_name = models.CharField(max_length=20)
poster_img = models.FileField()
poster_details = models.TextField()
homepage/views.py
from django.shortcuts import render_to_response
from .models import Poster, Poster_page
def poster(request):
pos = Poster.objects.all()
return render_to_response('index.html', {'pos':pos})
def poster_page(request, id=1):
poster_pg = Poster_page.objects.all()
return render_to_response('page.html', {'poster_pg':poster_pg})
homepage.url
from django.conf.urls import url
from.views import poster, poster_page
urlpatterns = [
url(r'^',poster),
url(r'^home/(?P<id>/d+)/$', poster_page),
]
poster.url
from django.conf.urls import url, include
from django.contrib import admin
from django.conf import settings
from django.conf.urls.static import static
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^home/',include('homepage.urls', namespace='home'))
]
if settings.DEBUG:
urlpatterns += static(settings.STATIC_URL,
document_root=settings.STATIC_ROOT)
urlpatterns += static(settings.MEDIA_URL,
document_root=settings.MEDIA_ROOT)
index.html
<body>
<div class="row">
{% for poster in pos %}
<div class="col-md-4">
<img src="{{ poster.poster_img.url }}" alt="image"><h3>{{ poster.poster_name }}</h3>
</div>
{% endfor %}
</div>
page.html
<body>
<div class="row">
<img src="{{ poster_img.url }}" alt="image"><h2>{{ poster_name }}</h2>
</div>
<div class="row">
<h2>{{ poster_details }}</h2>
</div>
homepage.url
Replace d/+ by \d+
from django.conf.urls import url
from . import views
urlpatterns = [
url(r'^$',views.poster),
url(r'^(?P<id>\d+)/$', views.poster_page),
]
Then Try:
from django.shortcuts import render,get_object_or_404
def poster_page(request, id):
poster_pg = get_object_or_404(Poster_page, id=id)
return render_to_response('page.html', {'poster_pg':poster_pg})
and yes you also need <a href="/home/{{poster.id}}/">.
In index.html you have not defined correct url in href to open poster detail.
Correct syntax would be like this:
<img src="{{ poster.poster_img.url }}" alt="image"><h3>{{ poster.poster_name }}</h3>
I think the issue is in the view with the context variable -
return render_to_response('index.html', {'pos':pos})
should be -
return render_to_response('index.html', {'poster':pos})
Because in you are calling {{poster.id}} in index template.
I have a model where I have an image name, image description, and an image. I want to use these fields to display a div with the image description and name with the thumbnail for each row in my model. Right now when I am trying to render the template I am getting:
TypeError: 'ImageFieldFile object is not subscriptable
During handling of the above exception another error occured:
ImportError: No module named 'backends'
Code:
Models.py
class PictureType(models.Model):
name = models.CharField(max_length = 150)
description = models.CharField(max_length = 1000)
image = models.ImageField(upload_to='AppName/images/')
views.py
class indexView(generic.ListView):
model = PictureType
template_name = 'index.html'
index.html
{% for visual in object_list %}
<div class="col-sm-4">
<div class="thumbnail">
<a href="#" class="">
<div align="center" class={{ visual.name }}>
<h4 class="">{{ visual.name }}</h4>
<p class="">{{ visual.description }}
</p>
</div>
<img src= "{{ visual.image.url }}" alt="..." class="">
</a>
</div>
</div>
{% endfor %}
settings.py
MEDIA_ROOT = os.path.join(os.path.dirname(__file__), 'media')
MEDIA_URL = '/media/'
urls.py
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^$', indexView.as_view(), name = 'index'),
]
urlpatterns += staticfiles_urlpatterns()
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
UPDATE:
When I change:
<img src= "{{ visual.image.url }}" alt="..." class="">
to
<img src= "{{ visual.image }}" alt="..." class="">
I don't get the above errors but the images don't come through either, they look like this:
Sounds like you are trying to import 'backends' module somewhere in your code, but it does not exist in the python path.
Hope this was helpful.
You have to tecth the Image URL from DataBase and Pass it to your HTML template file as context data type.
first you have to make sure that, you have been installed Pillow Library
(pip instal pillow)
And load static files to index.html file
{% load static %} - use this code on the begining of HTML
then change your view.py Function to :
class indexView(generic.ListView):
model = PictureType
users = PictureType.objects.all()
args = {'users':users}
template_name = 'index.html',args
or better way to Pass the data is change your Views as Function.
def indexView(request):
model = PictureType
users = PictureType.objects.all()
args = {'users':users}
return render(request,"index.html", args)