Need Help to display images from model - python

I have a model named 'Page' and i want to store many images for each Page object.
So i created a Separate Model named 'Image' as a F.K of 'Page' model.
In my template,, i am displaying all the Page object as a list (using bootstrap), but for each object, i also want to show many images saved for each object, i cant figure out the loop part. I have given relavent Code below :
Models.py
class Page(models.Model):
name=models.CharField(max_length=10,unique=True)
views = models.IntegerField(default=0)
slug = models.SlugField( )
#description field
des=models.TextField(max_length=500,blank=False)
def save(self, *args, **kwargs):
# Uncomment if you don't want the slug to change every time the name changes
#if self.id is None:
#self.slug = slugify(self.name)
self.slug = slugify(self.name)
super(Page, self).save(*args, **kwargs)
def __str__(self):
return self.name
def desti (instance,filename):
return "%s/%s/%s"%(instance.page,instance.user,filename)
class image(models.Model):
user=models.ForeignKey(User)
page=models.ForeignKey(Page)
images=models.ImageField(upload_to=desti, null=False ,blank=False)
Index.html
{% for obj in page_list %}
<div class="card" style="width: 20rem;">)
{% for obj2 in obj.images %}
<img class="card-img-top" src="{{ }}" alt="IMAGE GOES HERE">
<!-- want to display the images here as horizontal -->
{% endfor %}
<h1>this page has {{ obj.images }} images </h1>
<div class="card-block">
<h4 class="card-title">{{ obj.name }}</h4>
<p class="card-text">{{ obj.des }}</p>
ViewDetails
</div>
</div>
<hr>
{% endfor %}

Probably as simple as this:
class image(models.Model):
user=models.ForeignKey(User)
page=models.ForeignKey(Page, related_name='images')
pic =models.ImageField(upload_to=desti, null=False ,blank=False)
In template:
{% for page in page_list %}
<div class="card" style="width: 20rem;">)
{% for image_obj in page.images.all %}
<img class="card-img-top" src="{{ image_obj.pic.url}}" alt="IMAGE GOES HERE">
<!-- want to display the images here as horizontal -->
{% endfor %}
<h1>this page has {{ page.images }} images </h1>
<div class="card-block">
<h4 class="card-title">{{ page.name }}</h4>
<p class="card-text">{{ page.des }}</p>
ViewDetails
</div>
</div>
<hr>
{% endfor %}

Related

How to add multiple types of objects in a class

Here, is the problem when I try to add multiple objects to context through get function it is not showing pagination and when views.py is like below code then I am unable to add multiple objects of different models.
Ex: I want to add two models like Items and Ads to my Homepage class then how can I do this.
Views.py
class HomeView(ListView):
model = Item
paginate_by = 12
template_name = "home.html"
home.html
<div class="card-body text-center">
<a href="" class="grey-text">
<h5>{{ item.get_category_display }}</h5>
</a>
<h5>
<strong>
<a href="{{ item.get_absolute_url }}" class="dark-grey-text">{{ item.title }}
<span class="badge badge-pill {{ item.get_label_display }}-color">{{item.tag}}</span>
</a>
</strong>
</h5>
<h4 class="font-weight-bold black-text">
<strong>
{% if item.discount_price %}
<del>Rs. {{ item.price }}</del><br>
Rs. {{ item.discount_price }}
<span class="badge badge-pill danger-color">{{item.dis_per}}% off</span>
{% else %}
{{ item.price }}
{% endif %}
</strong>
</h4>
</div>
You need to change the get_context_data.
class HomeView(ListView):
model = Item
paginate_by = 12
template_name = "home.html"
def get_context_data(self, **kwargs):
# Call the base implementation
context = super().get_context_data(**kwargs)
context['ads'] = Ads.objects.filter(
some_condition='relevant ad')
return context
You can check it in the documentation, search for "Adding extra context"
https://docs.djangoproject.com/en/3.0/topics/class-based-views/generic-display/

Django telling me template doesn´t exist

Can anybody tell me why django is telling me that template does not exist?
I would like to go from the film_detail.html to film_report.html, when clicking on the "report"-button...
views.py
class FilmReport(LoginRequiredMixin, UpdateView):
model = Report
fields = ["comment", "reporter", "reports"]
# def __str__(self):
# return self.title
def form_valid(self, form):
form.instance.author = self.request.user
return super().form_valid(form)
urls.py
app_name = 'watchlist'
urlpatterns = [
path("", views.films_view, name="board-home"),
path("film/add", FilmAddView.as_view(), name="film-add"),
path("film/<int:pk>/", FilmDetailView.as_view(), name="film-detail"),
path("film/<int:pk>/report", FilmReport.as_view(), name="film-report")
]
film_detail.html
{% extends "board/base.html" %}
{% block content %}
<article class="media content-section">
<img class="rounded-circle film-img" src="/media/{{object.poster}}">
<!-- Mulighet for å ha en "add review"-knapp på siden der hvor filmene vises. -->
<i class="material-icons right">rate_review</i>add review
<i class="material-icons right">report</i>report
<div class="media-body">
<h2 class="film-title">{{ object.title }}</h2>
<p class="film-plot">{{ object.plot }}</p>
</div>
</article>
{% endblock content %}
film_report.html
{% extends "board/base.html" %}
{% block content %}
<h2>Film report</h2>
<!-- <article class="media content-section">
<img class="rounded-circle film-img" src="/media/{{object.poster}}">
<div class="media-body">
<h2 class="film-title">{{ object.title }}</h2>
</div>
</article> -->
{% endblock content %}
You didn't specify template name for your FilmReport class, so django assumed default name. Default name for UpdateView is <model_name>_form.html.
It's not the issue with FilmDetailView, because it's subclassed from DetailView, which is default to <model_name>_detail.html.
Either change name of your template from film_report.html to report_form.html or template_name='film_report.html' in FilmReport. Here's example from django docs and here's more in details about how it works.

How to integrate a function based view into a class based view in Django?

In my site I have 2 sections for users. The user posts page and the profile page. The profile page has all their info on it, so username, description, first/last name, etc. And the user posts page has all their posts on it. However, I want to integrate them together somehow.
Here is some of the code.
Here is the view for the User Posts
class UserPostListView(ListView):
model = Post
template_name = 'mainapp/user_posts.html'
context_object_name = 'posts'
def get_queryset(self):
user = get_object_or_404(User,username=self.kwargs.get('username'))
return Post.objects.filter(author=user).order_by('-published_date')
As you can see, I am returning the specific users posts.
And now here is my profile view
def view_profile(request,pk=None):
if pk:
user_profile = User.objects.get(pk=pk)
else:
user_profile = request.user
context = {'user':user_profile}
return render(request,'mainapp/profile.html',context)
It returns all the user's info.
Here is the HTML code for both the profile and user posts page
{% block content %}
<div class="profile-page-container">
<div class="profile-page-info">
<div class="profile-page-banner">
<div class="profile-page-banner-background">
<!-- <img src="https://cdn.pixabay.com/photo/2017/08/30/01/05/milky-way-2695569_960_720.jpg" alt="{{ user }}'s Background Image" > -->
</div>
<div class="profile-page-banner-text">
<h2 title="{{ user }}" id="username-profile-page">{{ user|safe|linebreaksbr|truncatechars_html:25 }} {% if user.userprofileinfo.verified %} <span class="image-profile-verified"><img draggable="false" title="Verified User" class="verifed" src="{% static 'images\verified.png' %}" alt="verified" width="25" height="25" srcset=""></span> {% endif %}</h2>
<p>{{ user.first_name }} {{ user.last_name }}</p><br>
</div>
</div>
<div class="profile-page-user-desc-box">
<p>{{ user.userprofileinfo.description }}</p>
<p>{{ user.userprofileinfo.website }}</p>
<p>{{ user.userprofileinfo.joined_date |date:"F d Y" }}</p>
</div>
<br>
{% if user.userprofileinfo.image %}
<img class="rounded-circle account-img" src="{{ user.userprofileinfo.image.url }}" alt="{{ user }}'s Profile Picture'">
{% endif %}
</div>
<div class="user-post-user-profile-page">
<h1 title="{{ user }}">Posts</h1>
{% for post in posts %}
<div class="content">
<div class="post">
<h1 class='posttitle'>{{ post.title }}</h1>
<img class="user-image" src="{{ post.author.userprofileinfo.image.url }}" alt="pfp" width="20%" height="20%">
{% if post.published_date %}
<!-- <div class="postdate">
<i class="fas fa-calendar-day"></i> <p>Posted {{ post.published_date|timesince }} ago</p>
</div> -->
<div class="posted-by">
<p>Posted by <strong>{{ post.author }}</strong> {{ post.published_date|timesince }} ago</p>
</div>
{% else %}
<a class="pub-post" href="{% url 'mainapp:post_publish' pk=post.pk %}">Publish</a>
{% endif %}
<p class='postcontent' >{{ post.text|safe|linebreaksbr }}</p>
</div>
</div>
{% endfor %}
</div>
</div>
{% endblock %}
And here is the user_posts page
{% block content %}
<div class="sidebar">
<p class="active" href="#">{{ view.kwargs.username }}</p>
<button class="commentbtn"><a class="aclass" href="#">Connect with {{ view.kwargs.username }}</a></button>
<p>{{ user.userprofileinfo.email }}</p>
<p>Lorem</p>
</div>
{% for post in posts %}
<div class="content">
<div class="post">
<h1 class='posttitle'>{{ post.title }}</h1>
<img class="user-image" src="{{ post.author.userprofileinfo.image.url }}" alt="pfp" width="20%" height="20%">
{% if post.published_date %}
<!-- <div class="postdate">
<i class="fas fa-calendar-day"></i> <p>Posted {{ post.published_date|timesince }} ago</p>
</div> -->
<div class="posted-by">
<p>Posted by <strong>{{ post.author }}</strong> {{ post.published_date|timesince }} ago</p>
</div>
{% else %}
<a class="pub-post" href="{% url 'mainapp:post_publish' pk=post.pk %}">Publish</a>
{% endif %}
<p class='postcontent' >{{ post.text|safe|linebreaksbr }}</p>
</div>
</div>
{% endfor %}
{% endblock %}
I have tried to merge the FBV into the CBV by cutting it and pasting it below the get_queryset method So like this
def get_queryset(self):
#... code here
def view_profile(request,pk=None):
#... code here
However this did not work. I am just curious as to how I can integrate both together so I can have the best of both worlds in one place
EDIT: Here are the models
class UserProfileInfo(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE,max_length=30)
first_name = models.CharField(max_length=50)
last_name = models.CharField(max_length=50)
description = models.CharField(max_length=150)
website = models.URLField(max_length=200)
image = ProcessedImageField(upload_to='profile_pics',
processors=[ResizeToFill(150, 150)],
default='default.jpg',
format='JPEG',
options={'quality': 60})
joined_date = models.DateTimeField(blank=True,null=True,default=timezone.now)
verified = models.BooleanField(default=False)
def __str__(self):
return f'{self.user.username} Profile'
def save(self, *args, **kwargs):
super().save(*args, **kwargs)
and now the post
class Post(models.Model):
author = models.ForeignKey(User,related_name='posts',on_delete=models.CASCADE)
title = models.CharField(max_length=75)
text = models.TextField()
group = models.ForeignKey(Group,null=True,blank=True,related_name='posts',on_delete=models.CASCADE)
created_date = models.DateTimeField(default=timezone.now)
image = models.ImageField(upload_to='post_images',blank=True,null=True)
file = models.FileField(upload_to='post_files',blank=True,null=True)
published_date = models.DateTimeField(blank=True,null=True,auto_now_add=True)
comments_disabled = models.BooleanField(default=False)
NSFW = models.BooleanField(default=False)
spoiler = models.BooleanField(default=False)
tags = TaggableManager()
def __str__(self):
return self.title
def save(self, *args, **kwargs):
super().save(*args, **kwargs)
Also in continuation to Ian answer, if you have a direct relationship between models then you can simply get the posts for the particular user like this:
def view_profile(request,pk=None):
if pk:
user_profile = User.objects.get(pk=pk)
user_posts = Posts.objects.filter(user__id=pk) #<---add these
else:
user_profile = request.user
user_posts = Posts.objects.filter(user__id = request.user.id) #<---add these
context = {
'user':user_profile,
'user_posts':user_posts
}
return render(request,'mainapp/profile.html',context)
A simple class based view for getting a user:
class UserDetailView(DetailView):
model = User
template_name = 'mainapp/profile.html'
context_object_name = 'user'
Relationships (foreign keys) can be followed backwards. Every foreign key has a reverse relationship defined (unless you set reverse_name to +...) it will usually be named <modelname>_set on the model referenced by the foreign key
For example, the following two lines are equivalent
Post.objects.filter(author=user)
user.post_set.all()
This can be used in your profile template
{% for post in user.post_set.all %}
...
{% endfor %}

Django Foreign Key class not showing

The goal is to have a dashboard show a list of users in your area. The list of users works and it shows the Username. The only issue is I can't get the users images (ideally just have 1st image) to show. There are no error messages currently. Just nothing appearing.
models.py
class Images(models.Model):
image = models.ImageField(upload_to='profile_image', null=True, default='profile_image/none/no-img.png')
user = models.ForeignKey(User, on_delete=models.CASCADE, null=False)
class Profile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
bio = models.TextField(max_length=500, blank=True, null=True)
birth_date = models.DateField(null=True, blank=True)
...
views.py
class DashboardView(TemplateView):
template_name = 've/cp/dashboard.html'
#method_decorator(login_required)
def dispatch(self, *args, **kwargs):
return super(DashboardView, self).dispatch(*args, **kwargs)
def get(self, request, pk=None):
users = User.objects.exclude(id=request.user.id)
try:
favorite = Favorite.objects.get(current_user=request.user)
favorites = favorite.users.all()
except Favorite.DoesNotExist:
favorites = None
args = {
# 'users': users, 'favorites':favorites, 'images': images,
}
return render(request, self.template_name, args)
dashboard.html
<div class="col-12">
<h2>People near you</h2>
{% for user in users %}
<a href="{% url 've:view_profile_with_pk' pk=user.pk %}">
<!--THIS WORKS-->
<h4>{{ user.username }}</h4>
<p>{{ user.profile.bio }}</p>
<!--But not this... why..-->
<p>{{ user.images.image.url }}</p>
'''
Or this.. However it does work on view_profile page where
there is a pk. Seem like it's not finding images for users,
as this results in a "No images message on localhost
'''
{% if images %}
{% for img in images %}
<a href="{{ user.img.image.url }}" target="_blank">
<img src="{{ user.img.image.url }}" class="" style="max-width: 300px">
</a>
{% endfor %}
{% else %}
<p>No images</p>
{% endif %}
</a>
<!-- Favorites works great -->
{% if not user in favorites %}
<a href="{% url 've:change_favorites' operation='add' pk=user.pk %}">
<button type="button" class="btn btn-success">Add Favorite</button>
</a>
{% endif %}
{% endfor %}
</div>
You can get user's images direcly from user object using images_set attribute.
In your case you can do something like this:
{% for user in users %}
{% with first_image=user.images_set.first %}
{% if first_image %}
<a href="{{ first_image.image.url }}" target="_blank">
<img src="{{ first_image.image.url }}" class="" style="max-width: 300px">
{% endif %}
{% endwith %}
{% endfor %}

Django - Default Profile Picture not showing

I have a question about images and imagefields. However, the default picture I chose does not show up, only a blank circle. This was my default picture
Models.py
class UserProfile(models.Model):
user = models.OneToOneField(User)
description = models.CharField(max_length=255, default='')
city = models.CharField(max_length=100, default='')
website = models.URLField(default='')
def __str__(self):
return self.user.username
class ProfilePicture(models.Model):
user = models.ForeignKey(User)
image = models.ImageField(upload_to='profile_image', default='profile_image/Default.jpg')
Forms.py
class UploadPictureForm(forms.Form):
image = forms.ImageField()
profile.html
<div class="container">
<div id="left">
<div id="profilecard">
{% if user.userprofile.image %}
<img class="circular--square" src="{{ }}" width="200" height="200">
{% endif %}
<div id="info">
<br>
<h3>{{ user.first_name }} {{ user.last_name }}</h3>
<p>#{{ user }}</p>
<p>{{ user.userprofile.city }}</p>
<p>{{ user.userprofile.website }}</p>
<p><i>{{ user.userprofile.description }}</i></p>
</div>
</div>
The src tag in profile.html was not filed. If you want a default image to be used you can put an else tag in the template and point the src to a static file.
<div class="container">
<div id="left">
<div id="profilecard">
{% if user.userprofile.image %}
<img class="circular--square" src="{{ user.userprofile.image.url }}" width="200" height="200">
{% endif %}
<div id="info">
<br>
<h3>{{ user.first_name }} {{ user.last_name }}</h3>
<p>#{{ user }}</p>
<p>{{ user.userprofile.city }}</p>
<p>{{ user.userprofile.website }}</p>
<p><i>{{ user.userprofile.description }}</i></p>
</div>
</div>
</div>
</div>
There is error in your code that you cannot get image from inside userprofile model so you need to do this:
Change your:
{% if user.userprofile.image %}
to:
{% if user.profilepicture_set.count > 0 %}
Change src attrib of img tag to:
src="{{ user.profilepicture_set.all.0.image.url }}"
Fixed code:
<div class="container">
<div id="left">
<div id="profilecard">
{% if user.profilepicture_set.count > 0 %}
<img class="circular--square" src="{{ user.profilepicture_set.all.0.image.url }}" width="200" height="200">
{% endif %}
<div id="info">
<br>
<h3>{{ user.first_name }} {{ user.last_name }}</h3>
<p>#{{ user }}</p>
<p>{{ user.userprofile.city }}</p>
<p>{{ user.userprofile.website }}</p>
<p><i>{{ user.userprofile.description }}</i></p>
</div>
</div>
</div>
</div>
Using related_name on your ForeignKey in ProfilePicture class will customize profilepicture_set key of user
user = models.ForeignKey(User, related_name='image')
You can access it on template like
{% if user.image.count > 0 %}
<img class="circular--square" src="{{ user.image.all.0.image.url }}" width="200" height="200">
{% endif %}
Also you can use OneToOneField to ProfilePicture User field if profile picture will be only one:
user = models.OneToOneField(User)
and template:
{% if user.profilepicture %}
<img class="circular--square" src="{{ user.profilepicture.image.url }}" width="200" height="200">
{% endif %}

Categories

Resources