displaying images using for loop in html - python

I am pretty new to django and now I'm currently learning how to access images in database and display it using html. I want to put the images as elements in a list for further styling and making the page responsive using css but I don't want to write each and every image as a list item as there are more than 100 images in database. I've tried the below code but its not displaying images as a list. Please do suggest if any better way of doing it. I have image as a model in my models.py.
<div class='gallery'>
{% for x in photo %}
<ul>
<li><img class="images" src="{{x.image.url}}"/></li>
</ul>
{% endfor %}
</div>
This is the model for reference:
from django.db import models
class Photo(models.Model):
photo_uploader = models.CharField(max_length=50)
desc = models.CharField(max_length=300)
image = models.ImageField(upload_to="home/images")
This is the view:
def profile(request):
username = None
if request.user.is_authenticated:
photos_to_show = []
username = request.user.username
photos = Photo.objects.filter(photo_uploader=username)
return render(request, 'profile.html', {'name': username, 'photo': photos})

The <ul> tags should be placed outside the loop, otherwise you each time start a new <ul> and end that </ul> per image:
<div class='gallery'>
<ul>
{% for x in photo %}
<li><img class="images" src="{{ x.image.url }}"/></li>
{% endfor %}
</ul>
</div>

Related

How to use greater than operator in django template

I am having an issue while implementing greater than operator in my template. I have a post in homepage which users can like and I have my friends' profile images displayed beside like count who like the post. Now if 10 friends like my post, i want only five of my friends' profile images to be displayed, and there will be a "+" at the end of displayed images. The "+" signifies that there are more friends who like my post. I tried this but it doesn't work:
Model:
class Profile(models.Model):
user = models.OneToOneField(settings.AUTH_USER_MODEL,on_delete=models.CASCADE,blank=True,null=True)
profile_pic = models.ImageField(upload_to='ProfilePicture/', default="ProfilePicture/user-img.png", blank=True)
friends = models.ManyToManyField('Profile', related_name="my_friends",blank=True)
class Post(models.Model):
poster_profile = models.ForeignKey(settings.AUTH_USER_MODEL,on_delete=models.CASCADE, blank=True,null=True)
likes = models.ManyToManyField('Profile', related_name='image_likes', blank=True)
View:
def home(request):
#all post in homepage
posts = Post.objects.filter(poster_profile=request.user)
#Show friend who liked Post
friends_like_img = request.user.profile.friends.all().order_by('-id')
context = {'posts':posts,'friends_img':friends_img}
return render(request, 'template.html', context)
Template:
{% for post in posts %}
{% for img in friends_img %}
{% if img in post.likes.all > 20 %}
<img src="{{ img.profile_pic.url }}" height="25" width="25" alt="profile_pic">
{% else %}
<img src="{{ img.profile_pic.url }}" height="25" width="25" alt="profile_pic"> +
{% endif %}
{% endfor %}
{% endfor %}
Your code is a bit of a mess, but here are some pointers:
You only ever want five images, so take care of that in the view by slicing the queryset:
friends_like_img = request.user.profile.friends.all().order_by('-id')[:5]
Your template syntax is all off, you could do with reading the docs and getting used to some examples. In the context, you're using friends_img, not friends_like_img - the context is what the template cares about. Now, since we only ever have five images, we can do this in the template:
{% for img in friends_img %}
<img src="{{ img.profile_pic.url }}" ...>
{% endfor %}
{% if post.likes.count > 5 %}
+
{% endif %}

Django displaying model on web page

I'm not sure where I'm going wrong. I'm creating a web store using Django/HTML/Foundations and I can't get the products that are in the database to display on the web page. I know they're in the database because when i go to admin page, they show up.
Here's the HTML piece:
{% for products in Product %}
<div class="column">
<h5>Title: {{products.product_name}}</h5>
<h5>Type: {{products.product_type}}</h5>
<h5>Price: {{products.sales_price}}</h5>
<img class="thumbnail" src="http://placehold.it/550x550">
</div>
{% endfor %}
Here's the Model:
class Product(models.Model):
product_name = models.CharField(max_length=255)
product_type = models.CharField(max_length=100)
sales_price = models.CharField(max_length=10)g
def __str__(self):
return self.product_name + " " + self.product_type + " " + self.sales_price
The only thing in my views.py for products page is: (might be where my problem lies)
def products(request):
return render(request,"products.html")
I'm new to django and python. Could someone please explain what's happening? Thanks
Your view needs to provide the products information to the template by using the context argument. See the documentation for render().
views.py:
def products(request):
context = {'products':Product.objects.all()}
return render(request,"products.html",context)
products.html:
{% for product in products %}
<div class="column">
<h5>Title: {{product.product_name}}</h5>
<h5>Type: {{product.product_type}}</h5>
<h5>Price: {{product.sales_price}}</h5>
<img class="thumbnail" src="http://placehold.it/550x550">
</div>
{% endfor %}
Have you tried changing your for loop from
{% for products in Product %}
to
{% for product in products %}
because you want to display a single product from the group of products each time you process through the loop.

Django: best way to handle foreign key requests in template pages

Suppose you are making a site to simply list your products.
You want to upload an unspecified number of pictures for your each of your products. So you, following Django's many-to-one documentation, make two models:
# files stored under my_app/static/my_app/product_images/product_<id>/<img_name>
def product_img_dir_path(instance, filename):
return 'my_app/static/my_app/product_images/product_{0}/{1}'.format(instance.product.id, filename)
class Product(models.Model):
name = models.CharField ...
... # other attributes of the product, e.g. price, etc
class ProductImage(models.Model):
product = models.ForeignKey("Product", on_delete=models.CASCADE)
image = models.ImageField(upload_to=product_img_dir_path)
Now if I want all of the images for say product 1, I can retrieve them using:
ProductImages.objects.filter(product__pk=1)
My question starts here.
Suppose you want an index page which just shows the listings for all of your products and for simplicity, the first image associated with each product.
You make a template page with
{% for product in product list %}
<div class="product-listing" style="display:inline">
<!-- image for product goes here -->
<!-- brief description goes here -->
</div>
{% endfor %}
where product_list was passed in your context:
# inside /my_app/views.py
def index(request):
...
context = {"product_list": Product.objects.all()}
...
Question: what is the best way to also have access to the images for displaying the images in the template page?
Currently I thought constructing a parallel image list would suffice:
# inside /my_app/views.py
def index(request):
...
product_list = Product.objects.all()
image_list = [product.productimage_set.all()[0] for product in product_list]
context = {"product_list": product_list, "image_list": image_list}
...
and then somehow using the forloop counter to get the corresponding image for the product.
e.g.
{% for product in product list %}
<div class="product-listing" style="display:inline">
<img src="{{ image_list[<forloop counter>].image.url }}" />
<!-- brief description goes here -->
</div>
{% endfor %}
Is there a better way to do this?
As long as you can access product.productimage_set, you can try to iterate it in your template and do not pass it as a view context.
In your Django template:
{% for product in product_list %}
<div class="product-listing" style="display:inline">
{% for product_image in product.productimage_set.all %}
<img src="{{ product_image.image.url }}" />
<!-- brief description goes here -->
{% endfor %}
</div>
{% endfor %}
I think that it will be easier for you to solve this if you simplify your design by moving the images to your Product model.
If you want to save the path to an image it will be easier to use CharField, but if you want to save many paths why not using JSONField?
My suggestion look like this:
class Product(models.Model):
name = models.CharField(null=True, blank=True)
main_image = models.CharField(null=True, blank=True) # Optional
images = JSONField(null=True, blank=True)

Access foreign key image in template

I have the following models:
class Car(models.Model):
# some fields
class CarPhotos(models.Model):
image = models.ImageField(upload_to='somewhere')
car = models.ForeignKey(Car)
in views.py:
def car_list(request):
cars = Car.objects.all()
return render(request, 'borsa/car_list.html', {'cars': cars})
in car_list.html:
{% for car in cars %}
<a href="car/{{ car.pk }}/view/">
<img class="media-object tmbpic" src="{{ car.carphotos_set.all.0.image.url }}" alt="kola">
</a>
The first method I've used was to use inline formsets but I had no clue how to access the images. Can you please point me in the right direction of how to access images according to Car objects ? I mean every Car must have a couple of images and I need to display only the first one in list view, but then I need to display all of them in Detail view.
To display all of them, you need to do something like:
{% for car in cars %}
{% for photo in car.carphotos_set.all %}
<img src="{{ photo.image.url }}">
{% endfor %}
{% endfor %}
So loop through the cars, then nest-loop through the images per car.

Python/Django - Get value of a ManyToManyField in a for tag

I can't get the image related value when I'm using {% for %} with the class Article. I tried with select_related, but I don't know how to define image to be correctly in displayed in the src="" attribute of my <img /> tag
Is there a clean way to make appear as I want?
models.py
class Image(models.Model):
gallery = models.ManyToManyField(Gallery)
name = models.CharField(max_length=100)
image = models.ImageField(upload_to='static/images/gallery')
def __str__(self):
return self.name
class Article(models.Model):
section = models.ForeignKey(Menu)
title = models.CharField(max_length=100)
text = models.TextField()
type = models.ForeignKey(Type)
image = models.ManyToManyField(Image)
def __str__(self):
return self.title
views.py
def index(request):
slider = Article.objects.all()
images = Image.objects.all()
return render(request, 'cms/index.html', locals())
template
{% for i in slider %}
<li>
<img src="{{i.image}}" alt="{{i.title}}"/>
<h2>{{i.title}}</h2>
<p>{{i.text}}, {{i.image_url}}</p>
</li>
{% endfor %}
You have to use 2 forloop for displaying images in manytomany table.
{% for i in slider %}
<li>
{% for im in i.image.all %}
<img src="{{im.image.url}}" alt="{{im.name}}"/>
{% endfor %}
<h2>{{i.title}}</h2>
<p>{{i.text}}, {{i.image_url}}</p>
</li>
{% endfor %}
Article.image is a ManyToMany field. Which image You want to display? First?
<img src="{{i.image.all.0.image.url}}" alt="{{i.title}}"/>
All?
{% for im in i.image.all %}
<img src="{{im.image.url}}" alt="{{im.name}}"/>
{% endfor %}

Categories

Resources