Django create path to an image file - django

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 %}"

Related

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.

Django: Insert image in a template whose path is dynamic

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">

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"

Resolve Static URL on Server

All of my user's have the option to link a profile picture. There are several templates that need to load this profile picture. If the user has not uploaded a picture, we use a default. When I want to display this profile picture, my code looks like this
<img src="{% if user.profile_picture.search_thumbnail.url %}{{ user.profile_picture.search_thumbnail.url }}{% else %}{% static "alternate.jpg" %}{% endif %}">
This is way too verbose for me, especially considering I need to repeat it out in multiple templates. I could use {% with %} blocks to store user.profile_picture.search_thumbnail.url, but that won't help me too much.
My solution was to write a function attached to the user model that returns the url of the static file. Unfortunately, the {% static %} is a template function. {% url %} has an equivalent function on the server called django.core.urlresolvers.reverse(). Does the alternative thing exist for the {% static %} tag?
In case anyone asks, I want to use the static function because my static files are stored in different places depending on the environment. My dev machine serves files locally, while my PRD machine serves static files from s3.
Thank you,
Nick
why not write a filter so you can do this.
<img src="{{ user.profile_picture.search_thumbnail.url|custom_filter }}">
and in the custom_filter you read from the settings.STATIC_URL to return the correct URL the user one is not set.
you could make the filter even shorter like this
<img src="{{ user|user_pic_url }}">
and in the filter pull out the .profile_picture.search_thumbnail.url /checks
This is what the static templatetag does underneath, and you can use it just fine in your own code:
from django.contrib.staticfiles.storage import staticfiles_storage
def static(path):
return staticfiles_storage.url(path)

Django string concatenation inside template tag best practice

I'm trying to concatenate some strings to format a URL inside my template tag, but I don't find an elegant way.
So far, what I have is:
{% button "Activate" "http://" site.domain url 'registration_activate' activation_key %}
Is there any best practice to make it a bit more "readable"?
Thanks a lot
You can concatenate two strings in Django template as follows:
{{"First String "|add:"Second String"}}
Just replace the two strings with your own variable.
What I use when I want to concatenate strings in Django templates from variables (examples taken from my own code, tell me if you need something closer to your case):
<html>
<input id="myid_{{idBase}}_{{idFinal}}" type="checkbox"></input>
</html>
and inside a django tag, I use the keyword "add" associated with the keywork with
{% with 'images/'|add:file_name as image_static %}
<img src="{% static image_static %}" title = "{{ tooltip }}" alt = "{{ title }}"/>
{% endwith %}