python for statement with if inside it - django

Need help please. I'm trying to get this if statement within a for statement correct, but failing miserably at it. If an image isn't available, I badly need a fallback image to replace it.
Thank you
{% for post in posts|slice:":1" %}
<div class="container">
{% if post.image.url %}
<div class="flex-item">
<img style="width:100%;" src="{{ post.image.url }}"
</div>
{% else %}
<div class="image-container1">
<img src="{% static 'images/fallback.png' %}" alt="" style="width: 100%;text-align: center;display: block;">
</div>
{% endif %}
{% endfor %}

You are not closing a div, which you opened just after first loop, also assuming that you are loading static on top.
P.S. I can't add comment, so posting it as ans.

Related

Django templates avoid loop

I am working on a project and I have a slight confusion.
The Django Template index.html has following code:
<div class="carousel-item active">
{% for i in products|slice:"0:"%}
<div class="col-xs-3 col-sm-3 col-md-3">
<div class="card" style="width: 17rem;">
<div class="card-body">
{% for img in i.images.all %}
{% if forloop.counter == 1 %}
<img src={{img.img_url}} class="card-img-top" alt="...">
{% endif %}
{% endfor %}
<h6 class="card-title">{{i}}</h6>
{% for skus in i.skus.all %}
{% if forloop.counter == 1 %}
<h6 class="card-price">{{skus.price}} {{skus.currency}}</h6>
{% endif %}
{% endfor %}
Add to Cart
</div>
</div>
</div>
{% endfor %}
</div>
In this code, is there a way to eliminate the {% for skus in i.skus.all %}?
The all tag is getting all objects, but I am restricting the loop to run only one time through the if condition so that I can only get the first item.
Is there a way to eliminate the loops that have .all in them and restrict the statement to run only one time though any other way?
You can achieve by using either with tag to set a variable or direclty us as:
{% with skus=i.skus.first %}
<h6 class="card-price">{{skus.price}} {{skus.currency}}</h6
{% endwith %}
or
<h6 class="card-price">{{i.skus.first.price}} {{i.skus.first.currency}}</h6
You may be looking for the first queryset method:
<div class="card-body">
<img src={{i.images.first().img_url}} class="card-img-top" alt="...">
</div>

Hide title if for statement is is empty

I have an image gallery for each users post. However, if a user has not uploaded any images I don't want to display the title "Image Gallery". How would I go about hiding the title if the for loop does not return anything?
<a>Image Gallery</a>
<div class="row">
{% for images in postgallery %}
<div class="col-md-3">
<a href="{{ images.images.url }}" data-lightbox="image-1">
<img class="img-thumbnail" src="{{ images.images.url }}" />
</a>
</div>
{% endfor %}
</div>
I have tried a few variations of {% if imagegallery == 0 %} but I can't get anything to work as I would like
According to django doc you can use this syntax: {% if postgallery|length == 0 %}

Invalid block tag on line 66: 'endblock', expected 'empty' or 'endfor'. Did you forget to register or load this tag?

Why is it giving me this strange error: Did you forget to register or load this tag? it was working fine but when i did some changes in this code it started this error... i was going through question related to this issue but could not find the solution....
<div class="container">
<div class="row">
<div class="pagination">
{% for item in post.object_list %}
<!-- {% for item in post %}-->
<div class="card my-3 text-white bg-dark mb-3" style="width: 18rem;">
<img src="/media/{{item.thumbnail}}" class="card-img-top" alt="...">
<div class="card-body">
<h5 class="card-title">{{item.title}}</h5>
<p class="card-text">{{item.intro}}</p>
<!-- href={% url 'bicep' %}-->
read more...
<!-- read more...-->
</div>
</div>
{% if forloop.counter|divisibleby:4 %}
</div>
{% endif %}
{% endfor %}
Django disregards HTML comments. That means django will run this code:
<!-- {% for item in post %}-->
This is what's causing the error because django is expecting an endfor closing tag for this loop.
Either remove this line from your code or use django's comment template tag to comment out the template related code:
{% comment %}
{% for item in post %}
{% endcomment %}

Jinja extends doesn't load image

I'm using Flask for a small web app and having trouble to get my background image to display after extending using Jinja.
My layout.html contains a header:
<!-- Header section -->
<header class="header-section">
<div class="header-warp">
<div class="container">
<a href="#" class="site-logo">
<img src="{{ url_for('static', filename='img/logo.png') }}" alt="">
</a>
<div class="user-panel">
{%if session.user_id %}
Logout
{% endif %}
</div>
<div class="nav-switch">
<i class="fa fa-bars"></i>
</div>
</div>
</div>
</header>
<!-- Header section end -->
<main>
{% block main %}
{% endblock %}
</main>
And in another html file, I want to extend the layout:
{% extends "layout.html" %}
{% block title %}
Register
{% endblock %}
{%block main%}
<section class="hero-section set-bg" data-setbg="{{ url_for('static', filename='img/review-bg.jpg') }}">
However, the review-bg.jpg doesn't load and instead, I received a blank section. However, when I straight up copying the layout (not using extends anymore), the image loaded correctly. I double checked with (http://127.0.0.1:5000/static/img/review-bg.jpg) and the path correctly return the image.
Anyone can help explain to me why Jinja doesn't load the image after extending?
The problem seems to be in data-setbg - it can be React script, look here:
html tag attribute "data-setbg" is not working in React project
Or try to google "data-setbg is not working"
Edit the extension to:
{% extends "layout.html" %}
{% block title %}
Register
{% endblock %}
{%block main%}
<img src="{{ url_for('static', filename='img/review-bg.jpg') }}" alt="">
Do you see the image now? If so (what I suspect), it's not jinja/flask related but something else is going on. If not, right click on the page in firefox and press view source. Where is the link pointing to?

How to create a film strip in django using bootstrap and for loop?

How do I display a group of 6 thumbnails in my template to create a filmstrip. The list i am iterating through a for loop has around 30 items i want to break it into chunks of 6 and show it as a filmstrip slider. I tried using the range function for the for loop but that doesnt work
<div class="carousel-inner">
<div class="item active">
<ul class="thumbnails">
{% for show in object_list %}
<li class="span2">
<div class="thumbnail">
<a href="{{ show.get_absolute_url }}" data-title="{{ show.name }}" >
{% if show.images.exists %}
{% with show.images.all.0.image as show_image %}
<img src="{% thumbnail show_image 160x160 crop %}" alt="{{show.name}}" class="thumbnail">
{% endwith %}
{% else %}
<img src="{% static 'img/default-image.gif' %}" alt="{{show.name}}" class="thumbnail">
{% endif %}
</a>
</div>
</li>
{%endfor%}
</ul>
</div>
If you want 1 carousel per 6 images then you could do it like this
Step 1) Create a new .html file in your templates folder called film-slider.html.
{% for reel in reels %}
<div class="carousel-inner">
<div class="item active">
<ul class="thumbnails">
{% for show in reel %}
<li class="span2">
<div class="thumbnail">
<a href="{{ show.get_absolute_url }}" data-title="{{ show.name }}" >
{% if show.images.exists %}
{% with show.images.all.0.image as show_image %}
<img src="{% thumbnail show_image 160x160 crop %}" alt="{{ show.name }}" class="thumbnail">
{% endwith %}
{% else %}
<img src="{% static 'img/default-image.gif' %}" alt="{{ show.name }}" class="thumbnail">
{% endif %}
</a>
</div>
</li>
{% endfor %}
</ul>
</div>
</div>
{% endfor %}
Step 2) In your templatetags/tags.py (create it if you haven't)
from django import template
register = template.Library()
def filmslider(reel):
reels = []
for i in range(0, len(reel), 6):
reels.append(reel[i:i+6])
return {'reels':reels}
register.inclusion_tag('film-slider.html')(filmslider)
This will make an inclusion tag that's available in your templates once you've loaded it via {% load tags %}.
This will make this work for you like this {% filmslider object_list %} which you will replace all the above html code that you posted with.
I haven't tested this but it should work, if in the future you want to have more functionality to this tag you can simply add arguments to the tag definition, I'll give an example.
def filmslider(reel, slides):
#do the code.
which will lead you to {% filmslider object_list 9 %} and voila, now you can extend your film reel from 6 slides to 9.
Hope this helps a bit!