Simple Steps to Send Emails with Static Images in Django
Context
I wanted to send an email with a template that included an image using send_mail
from Django. The image was stored in the static
folder of the Django project. I wanted to use the Django template system to generate the email content, but I was not sure how to reference the image in the template.
Requirements
I asume you have a Django project with a static folder and a template that you want to use to generate an email.
Issue with {% static %} in Emails
The first thing I tried was to use the {% static %}
template tag to generate the URL for the image. However, this
tag does not generate a full URL, but a relative URL. This is not a problem when the template is rendered in the
browser, but emails need a full URL to access the image.
This means that {% static %}
only appends the relative path to the STATIC_URL
, which is not sufficient for email clients to locate the image.
Solution - Generating Full URLs in the View (with code snippets)
The solution I found was to generate the full URL in the view and pass it as a context variable to the template.
This involves combining the site's domain with the static file path. This approach uses get_current_site
to fetch the
current site's domain and static
to get the static file path, concatenating these to form a complete URL.
In the view
This is an example code to demonstrate how to create the full URL in a Django view:
This URL is then passed to the email template context and used in the src attribute of the img tag.
Please note that you need to adapt the paths to your project.
# in views.py # imports we need to create the full URL from django.contrib.sites.shortcuts import get_current_site from django.templatetags.static import static # imports we need to render the template to use in the email from django.template.loader import render_to_string # imports we need to send the email from django.core.mail import send_mail def my_view(request): # or any other view # we get the current site to get the domain current_site = get_current_site(request) # we get the static file path and concatenate it with the domain logo_url = f'https://{current_site.domain}{static("images/your-logo.png")}' # we generate a context with the variables we want to use in the template context = { 'logo_url': logo_url, # ... other context variables ... } subject = 'Subject of your email' # we render the templates to use in the email message_plain = render_to_string('my_template.txt', context) message_html = render_to_string('my_template.html', context) email = '[email protected]' # we send the email send_mail(subject, message_plain, None, [email], html_message=message_html)
In the templates
When you send emails, it is recommended to provide both a plain text and an HTML version of the email. This is why we have two templates in the view.
HTML template
<!-- in my_template.html --> <img src="{{ logo_url }}" alt="Your Logo">
Plain text template
In my case, I did not need to include the image in the plain text version of the email, but if you need to do so, you can use the same approach as in the HTML template.
<!-- in my_template.txt --> Your Logo: {{ logo_url }}
Keep in mind
- This approach is not limited to images. You can use it to generate full URLs for any static file.
- This approach is not limited to emails. You can use it to generate full URLs for any static file in any context and render the templates.
Key Takeaways
- Django's
{% static %}
template tag only generates a relative URL, which is not sufficient for email clients to locate the image. - To generate a full URL for a static file, you need to combine the site's domain with the static file path.
- You can use
get_current_site
to fetch the current site's domain andstatic
to get the static file path, concatenating these to form a complete URL. - You can use this approach to generate full URLs for any static file in any context and render the templates.
- You construct the full URL in the view and pass it as a context variable to the template.
Happy coding!
Comments
Comments powered by Disqus