Django: Insert image in a template whose path is dynamic - django

I know I can insert an image in an html generated page based on a template using:
<img src="{% static "myapp/my_image.jpg" %}" alt="Image Description">
The problem is I want something slightly more complex. Let's say I have an object "user" in my template with a user.first_name and a user.last_name attributes. I would like to insert an image whose path would be:
<img src="{% static "myapp/{{user.first_name}}_{{user.last_name}}.jpg" %}" alt="Profile Picture">
This line is wrong, I get an error (Django can't parse the expression). Can someone help?
I am building kind of a organization chart with photographs, is that a proper way of including profile pictures for every member (based on the fact that the pictures should be named firstname_lastname.jpg)?
Thanks

You can do another thing:
<img src ="{% static 'myapp/' %}{{user.first_name}}_{{user.last_name}}.jpg" alt="Profile Picture">
This will work just as fine. Hope this helps :)

While I recommend creating the path in your view and passing it as context to your template, you can also use the add filter:
{% static "myapp/"|add:user.first_name|add:"_"|add:user.last_name|add:".jpg" %}
You could also create a custom template tag for this. Lots of options.

You'll have to use a custom filter (don't use add, that's not meant for adding strings).
<img src="{% static 'myapp/'|addstring:user.first_name|addstring:'_'|addstring:user.last_name|addstring:'.jpg' %}" alt="Profile Picture">
Where your custom filter addstring could be
# In : templatetags/<app>_extras.py
from django import template
register = template.Library()
#register.filter
def addstring(s1, s2):
return str(s1) + str(s2)
Another option is having a custom filter do all the magic & use that in img src:
#register.filter
def imgsrc(user):
return 'myapp/{}_{}.jpg'.format(user.first_name, user.last_name)

If the objective is just to set the dynamic image path. This worked for me. You can try this.
{% load static %}
<img src ="{% static 'images/myimage.jpg' %}" alt="My image" width="1500" height="333" id="plot" style="visibility: hidden"/>
<script>
function imageShow(){
var name="myname";
{% load static %}
var filename="{% static 'images/' %}"+name+".png";
document.getElementById("plot").src=filename;
document.getElementById("plot").style.visibility='vsible';
}
</script>

you can do like this.
<img src ="{% static "folder name"/ %}{{user.first_name}}_{{user.last_name}}.jpg" alt="Profile Picture">

Related

Django create path to an image file

I have a normal app that has a directory structure similar to the following:
...static/
Training/
css/
img/
js/
...templates/
....
Within one of my templates, I would like to get the image name from the database and build the path to the image. For example, if I had the image MyPicture.jpg, then I would like to include static and combine this with 'Training/img/' and the file name to get something like
'..path to static../Training/img/MyPicture.jpg'
I found the following article that suggested using template tags, so I have tried this:
from django import template
register = template.Library()
#register.filter
def addstr(arg1, arg2):
# Apparently, add has side effects, so use this:
# https://stackoverflow.com/questions/4386168/how-to-concatenate-strings-in-django-templates
return str(arg1) + str(arg2)
With the template:
{% with static|addstr:"Training/img/"|addstr:course.img as imgpath %}
<img class="card-img rounded-lg rounded-top" src="{{ imgpath }}" alt="Card image">
{% endwith %}
This is unfortunately leaving out the static part of the address.
How do I combine all three parts ?
[p.s. I have a {% load static %} at the top of the template ]
Thanks
Mark
if you wanna show the absolute full url, this is what you need:
{{request.scheme}}://{{request.META.HTTP_HOST}}{{object.filefield.url}}
but if you just need to show the file, you can use this:
<img class="card-img rounded-lg rounded-top" src="{{ object.filefield.url }}" alt="Card image">
Silly mistake really. All I needed to do was separate out the static and not treat it like a string. This works:
"{% static 'Training/img/'|addstr:course.img %}"

Django tag within URL tags

I would like to use dynamic images based on a a pk of the page.
To be clearer I have a survey app, using one question per page .. which mean that the user is presented a question he answers and is redirected to the next question. Each question has a different id and I would like to attach to each question an image.
Right now I have a static image lik that :
<div class="col-5">
<img src="{% static 'images/RightSpeech.jpg' %}" class="img-fluid" alt="Responsive image">
</div>
but I would like to make it dynamic.. I tried something like that with no success:
<div class="col-5">
<img src="{% static 'images/image{{question.pk}}.jpg' %}" class="img-fluid" alt="Responsive image">
</div>
any idea ?
The static tag doesn't really do anything more than adding the value of STATIC_URL to whatever you pass it. Instead of messing about with all these tags, you could just do this manually:
<img src="{{ STATIC_URL }}/images/image{{question.pk}}.jpg"
If for some reason the static context processor isn't activated, you can use the {% get_static_prefix %} tag in exactly the same way:
<img src="{% get_static_prefix %}/images/image{{question.pk}}.jpg"
You need to use
{% static 'images/image'|add:question.id|add:'.jpg' %}
in order to get concatenate the question PK to the image name. This just makes use of the concatenation filter |add:.
EDIT 1
If the above does not work, you can try to use the {% with %} tag, so in your case:
{% with "images/image"|add:question.id|add:".jpg" as customUrl %}
{% static customUrl %}
{% endwith %}
Hope this helps!

How can I avoid inline styling, yet take advantage of the templating language?

For each instantiation of an object in the template, I'd like to extract it's associated ImageField's url in order to show the photo. But I'm having trouble finding a way to do this without inline styling:
{% for entry in entries %}
<div class="row">
<div class="col s4">
<div class="card-panel" style="background-image: url('{{entry.image.url}}');">
<h1>{{entry.title}}</h1>
</div></div></div>
{% endfor %}
This works in bringing each individual image to the template, but I wonder if I can abstract away the css just to keep my css in a separate file.
edit: same goes for the <img> tag:
<img src="{{ entry.image.url }}">
this, in the template, would be dynamic. But I wouldn't be able to set this as a background-image
It is possible to use the Django template system to render CSS and create dynamic css files. I don't recommend doing this, but if you really want to you can set it up like normal url/view.
For example, your urls.py would have something like this
url(r'^dynamic_style/(?P<pk>\w+)$', dynamic_style, name='dynamic')
Then your view would look something like
def dynamic_style(request, pk):
entry = get_object_or_404(Entry, pk)
return render_to_response('dynamic_style.css', {
'image_url': entry.image.url
}, content_type='text/css')
Then in your template you could have
<link href="{% url 'dynamic_style' pk=entry.id %}" rel="stylesheet">
This is a clunky way to generate css. If you can use inline as suggested above, it's much better.

Doesn't show image in browser using variables inside static tag

I need to concatenate two strings inside a static tag, i checked previous question about how to concatenate strings in django template and i found this answer, but when i used that solution, the broser (Firefox) doesn't show the image.
Details:
This is my code, assume that the value of user.if is 1:
{% with "images/my_twitter_wordcloud_"|add:user.id|add:".png" as image_static %}
<center>
<img src="{% static 'image_static' %}" width="650" height="350" style="margin-left: 10%;"/>
</center>
{% endwith %}
When i ckecked the inspector in the browser, it showed the image like this:
<img src="/static/image_static" style="margin-left: 10%;" height="350" width="650">
I think that it should be:
<img src="/static/images/my_twitter_wordcloud_"|add:user.id|add:"png" style="margin-left: 10%;" height="350" width="650">
I checked the django documentation about add reference, and i tried using "" and "" after add, but It seems like django doesn't interpretate the variable, what i'm doing wrong?
Thanks for your help.
PD: i'm apologyze for my English.
Edit:
Doing what #Selcuk said, the inspector show me this:
<img src="/static/.png" style="margin-left: 10%;" height="350" width="650">
Is strange, even if i use '' instead of "", so i don't understand what is wrong, if i put this (where the value of user.id is 1):
<center><img src="{% static 'images/my_twitter_wordcloud_1.png' %}"
It show the image correctly.
Remove the quotes around image_static and use the variable name. That is, replace the following:
{% static 'image_static' %}
with this
{% static image_static %}
As a side note, you should also include a dot (.) before the image extension (png).
for future people who will come here.
avarage_rating can hold any single value from this list [0,1,2,3,4,5] including decimals.
so use a single variable as a value and the loading dynamic image is below.
{{avarage_rating | first }} == first digit and .svg is appended to it.
here s is the name of the image initial.
<code><img src="{% static 'img/s'%}{{avarage_rating | first }}.svg"><span>{{avarage_rating}}</span></code>

How do you dynamically display images in Django

I'm trying to dynamically display Images in Django. this is my details page
{% extends 'base.html' %}
{% load staticfiles %}
{% block header %}
<!-- Set your background image for this header on the line below. -->
<header class="intro-header" style="background-image: url('{% static 'blog/img/about-bg.jpg' %}')">
<div class="container">
<div class="row">
<div class="col-lg-8 col-lg-offset-2 col-md-10 col-md-offset-1">
<div class="page-heading">
<h1>{{ post.title }}</h1>
<hr class="small">
<span class="subheading">blog detail</span>
</div>
</div>
</div>
</div>
</header>
{% endblock %}
{% block content %}
<h1>{{ post.title }}</h1>
<h4>{{ post.body }}</h4>
{% lorem 5 p random %}
<hr>
<div id="disqus_thread"></div>
<script>
/**
* RECOMMENDED CONFIGURATION VARIABLES: EDIT AND UNCOMMENT THE SECTION BELOW TO INSERT DYNAMIC VALUES FROM YOUR PLATFORM OR CMS.
* LEARN WHY DEFINING THESE VARIABLES IS IMPORTANT: https://disqus.com/admin/universalcode/#configuration-variables
*/
/*
var disqus_config = function () {
this.page.url = PAGE_URL; // Replace PAGE_URL with your page's canonical URL variable
this.page.identifier = PAGE_IDENTIFIER; // Replace PAGE_IDENTIFIER with your page's unique identifier variable
};
*/
(function() { // DON'T EDIT BELOW THIS LINE
var d = document, s = d.createElement('script');
s.src = '//eights.disqus.com/embed.js';
s.setAttribute('data-timestamp', +new Date());
(d.head || d.body).appendChild(s);
})();
</script>
<noscript>Please enable JavaScript to view the
comments powered by Disqus.
</noscript>
<script id="dsq-count-scr" src="//eights.disqus.com/count.js" async></script>
{% endblock %}
So far I tried storing these approaches. I tried storing this in the database
{% static 'blog/img/about-bg.jpg' %}
and called it like this
style="background-image: url('{{ post.title }}')"
that didn't work. Then I tried storing it in the database like this
'blog/img/about-bg.jpg'
and calling it like this
style="background-image: url('{% static '{{ post.title }}' %}')
then I ried storing it like this in the database
static/blog/img/about-bg.jpg
and calling it like this
style="background-image: url('{{ post.title }}')"
I've also tried defining it in the views.py
pic = "path/pic.img"
context = {
"pic": pic
context and calling it
{{pic }}
none of these methods work. It's a little different from Laravel. In laravel
path/{{ post->title }}
would have worked. How can I do this in Django? any and all suggestions are welcome. To be clear I want all my articles to display an image on the index page, then when I click one of them, I am taken to the details page that image for that particular article is displayed
I've figured it out. It's supposed to be stored as
/static/blog/img/about-bg.jpg
not
static/blog/img/about-bg.jpg
the forward slash makes it work. in Laravel this does not matter
From you question I understand that by dynamically you mean that you want to upload an image to your site. So it's not just a static image that is always the same like a logo of your page or something.
You have to do this:
In models.py
from django.contrib.sites.models import Site
def generate_filename(filename): #it adds the image in a folder with the current year
ext = filename.split('.')[-1]
year = datetime.datetime.now().year
return str(year) + '/' + str(int(time())) + '.' + ext
class PageWithImage(models.Model):
image = models.ImageField(upload_to=generate_filename, blank=True, null=True)
site = models.ForeignKey(Site, blank=True, null=True)#this if you want the image linked with your site
Then in setting.py you have to add:
import os
BASE_DIR = os.path.dirname(os.path.dirname(__file__))
MEDIA_ROOT = os.path.join(BASE_DIR, 'img')
MEDIA_URL = '/img/'
Then in the template:
<img itemprop="image" src="http://{{ object.site }}{{ object.image.url }}">
And don't forget to add the image field to admin.py
For adding images dynamically to your webpage using Django :
As we mostly use Jinja for templates,
<img src="{%static 'images/beach.svg' %}" alt="A beach image">
We give this kind of commands to access static image files. But for dynamic, we have to change the 'beach.svg' to something like {{dest2.img}} in the above HTML image tag, if my "views.py" function is like :
def index(request):
dest2 = Destination() // Imported class 'Destination()' from models.py .
dest2.name = 'Beach'
dest2.img = 'beach.svg' // The image name we need.
dest2.desc = 'Some beach description'
dest2.price = 2000
return render(request, 'index.html', {'dest2' : dest2}) // Passing the object value to html page.
If we logically think, the code should be like :
<img src="{%static 'images/{{dest2.img}}' %}" alt="A beach image"> // we cannot do this here!!!
We cannot use a Jinja code inside another Jinja code. So we add :
{% static 'images' as base_url %}
at the top of our HTML page. 'images' is the default folder for images and we are calling it as 'base_url' in this HTML page. So we have to use 'base_url' as path and 'dest2.img' as the file name. so the image source will be like :
<img src="{{base_url}}/{{dest2.img}}" alt="A beach image">
So finally we're done making the dynamic images in Django.!!!😋
First, you cannot use {% static 'blablabla' %} in CSS files.
Second, use this code:
style="background: url(/static/blog/img/about-bg.jpg) no-repeat"
Third, if you will be working with images from models in the future then your code should be:
style="background: url(/{{ your_object.your_img_field }}) no-repeat"