Syntax for using {{ article.image }} inside {% static %} with django templates - django

Trying to display an image on a webpage with django templates
{% for article in article_roll %}
<li><div class="blog-post" id="blog{{ forloop.counter }}">
{% load static %}
<img src="{% static '{{ article.image }}' %}" alt="{{ article.alt }}">
<div class="blog-post-preview">
<span class="blog-title">{{ article.image }} {{ article.title }}</span>
<span class="blog-date">{{ article.date }}</span>
</div>
<span class="blog-text">{{ article.preview }}</span>
</div></li>
{% endfor %}
This is the part that's giving me trouble
<img src="{% static '{{ article.image }}' %}" alt="{{ article.alt }}">
{{ article.image }} is an ImageField in an SQLite Database setup with the default configurations django has. My main concern is loading up the correct image for each article as the for loop progresses, but I can't even get {{ article.image }} to evaluate to anything useful within the {% static %} braces.
the static url comes out as
<img src="/static/%7B%7B%20article.image%20%7D%7D" alt="image thing">
When what I'm trying to get is
<img src="/static/value_of_{{article.image}}" alt="image thing">
I've tried escaping characters, avoiding using ' ', and rewriting the urls.
I feel like I might be approaching this problem entirely wrong and there's a better way to do it, but I've been looking through the documentation and haven't seen anything obvious to me.

You don't need the '{{ }}' inside the static tag.
<img src="{% static article.image %}" alt="{{ article.alt }}">

Related

python for statement with if inside it

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.

How can I check if url_for references an existing file?

I am serving pictures from a loop. Some of the referenced URL's do not exist though. In that case I want to reference to a default pic.
I tried
{% for hit in hits %}
{% if url_for('static', filename='pictures/' + hit['jpg']) %}
<img class="rounded-circle article-img" src="{{ url_for('static', filename='pictures/' + hit['jpg']) }}">
{% else %}
<img class="rounded-circle article-img" src="{{ url_for('static', filename='pictures/' + 'default.jpg') }}">
{% endif %}
{% endfor %}
which seemed to be a bit naive since it didn't change anything. Do you have an idea for a good way to handle this?
You can always chose the right image path before rendering the template. So maybe something with os.path.isfile:
import os
from Flask import render_template
...
for i in range(len(hits)):
if not os.path.isfile('relative/path/to/pictures/' + hits[i]['jpg']):
hits[i]['jpg'] = 'default.jpg'
render_template('/my/template.html', hits = hits, ...)
Template:
{% for hit in hits %}
<img class="rounded-circle article-img" src="{{ url_for('static', filename= 'pictures/' + hit['jpg']) }}">
{% endfor %}

How to zoom on hover with Django-Oscar image

I am using Django-Oscar with AWS S3 to host my product images. The carousel that displays images is presenting the product images correctly, but it is showing the thumbnail size image. I want to display the full-size image, not the thumbnail, on hover or click.
I am using django-compressor as well, so the images are stored in the cache folder on S3.
Should I change the template to enable this, or is there a django-oscar setting that can handle this?
Relevant code:
<div class="carousel-inner" role="listbox">
{% for image in all_images %}
<div class="item {% if forloop.first %}active{% endif %}">
{% thumbnail image.original "440x400" upscale=False as thumb %}
<img src="{{ thumb.url }}" alt="{{ product.get_title }}" />
{% endthumbnail %}
</div>
{% endfor %}
</div>
To something like this:
<div class="carousel-inner" role="listbox">
{% for image in all_images %}
<div class="item {% if forloop.first %}active{% endif %}">
<a href="{{ image.url }}" target="_blank">
{% thumbnail image.original "440x400" upscale=False as thumb %}
<img src="{{ thumb.url }}" alt="{{ product.get_title }}" />
</a>
{% endthumbnail %}
</div>
{% endfor %}
</div>

Sorl-Thumbnail static image in default

I use Sorl-Thumbnail in my django-project. I have a situation, when I havent got an image and I need to show no_image.png.
This code works:
{% thumbnail car.default_picture.image|default:"http://example.com/img/no_image.png" "240x180" crop="center" as im %}
<img src="{{ im.url }}" width="{{ im.width }}" height="{{ im.height }}">
{% endthumbnail %}
But I want to use {% static "img/no_image.png" %} in default. I have an error:
TemplateSyntaxError: Syntax error. Expected: ``thumbnail source geometry [key1=val1 key2=val2...] as var`
How to fix it? Thanks.
I just found this alternative too:
{% thumbnail product.logo "200x200" crop="center" as im %}
<img src="{{ im.url }}" width="{{ im.width }}" height="{{ im.height }}">
{% empty %}
<img src="{% static 'images/default.gif' %}" width="200" height="200">
{% endthumbnail %}
{% if car.default_picture.image %}
thumbnail
{% else %}
{% static "img/no_image.png" %}
{% endif %}
It works for me

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!