<?xml version="1.0" encoding="utf-8"?>
<?xml-stylesheet type="text/xsl" href="../assets/xml/rss.xsl" media="all"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Diego A. Carrasco Gubernatis | Personal Website (Posts about email)</title><link>https://diegocarrasco.com/</link><description></description><atom:link href="https://diegocarrasco.com/categories/email.xml" rel="self" type="application/rss+xml"></atom:link><language>en</language><copyright>Contents © 2026 &lt;a href="mailto:hi@diegocarrasco.com"&gt;Diego Carrasco G.&lt;/a&gt; </copyright><lastBuildDate>Sat, 11 Apr 2026 08:03:45 GMT</lastBuildDate><generator>Nikola (getnikola.com)</generator><docs>http://blogs.law.harvard.edu/tech/rss</docs><item><title>Simple Steps to Send Emails with Static Images in Django</title><link>https://diegocarrasco.com/sending-emails-static-images-django/</link><dc:creator>Diego Carrasco G.</dc:creator><description>&lt;figure&gt;&lt;img src="https://diegocarrasco.com/images/social-images/sending-emails-static-images-django.jpg"&gt;&lt;/figure&gt; &lt;div class="toc"&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://diegocarrasco.com/sending-emails-static-images-django/#context"&gt;Context&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://diegocarrasco.com/sending-emails-static-images-django/#requirements"&gt;Requirements&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://diegocarrasco.com/sending-emails-static-images-django/#issue-with-static-in-emails"&gt;Issue with {% static %} in Emails&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://diegocarrasco.com/sending-emails-static-images-django/#solution-generating-full-urls-in-the-view-with-code-snippets"&gt;Solution - Generating Full URLs in the View (with code snippets)&lt;/a&gt;&lt;ul&gt;
&lt;li&gt;&lt;a href="https://diegocarrasco.com/sending-emails-static-images-django/#in-the-view"&gt;In the view&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://diegocarrasco.com/sending-emails-static-images-django/#in-the-templates"&gt;In the templates&lt;/a&gt;&lt;ul&gt;
&lt;li&gt;&lt;a href="https://diegocarrasco.com/sending-emails-static-images-django/#html-template"&gt;HTML template&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://diegocarrasco.com/sending-emails-static-images-django/#plain-text-template"&gt;Plain text template&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="https://diegocarrasco.com/sending-emails-static-images-django/#keep-in-mind"&gt;Keep in mind&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://diegocarrasco.com/sending-emails-static-images-django/#key-takeaways"&gt;Key Takeaways&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://diegocarrasco.com/sending-emails-static-images-django/#references"&gt;References&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;h2 id="context"&gt;Context&lt;/h2&gt;
&lt;p&gt;I wanted to send an email with a template that included an image using &lt;code&gt;send_mail&lt;/code&gt; from Django. The image was stored in the &lt;code&gt;static&lt;/code&gt; 
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.&lt;/p&gt;
&lt;h2 id="requirements"&gt;Requirements&lt;/h2&gt;
&lt;p&gt;I asume you have a Django project with a static folder and a template that you want to use to generate an email.&lt;/p&gt;
&lt;h2 id="issue-with-static-in-emails"&gt;Issue with {% static %} in Emails&lt;/h2&gt;
&lt;p&gt;The first thing I tried was to use the &lt;code&gt;{% static %}&lt;/code&gt; 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.&lt;/p&gt;
&lt;p&gt;This means that &lt;code&gt;{% static %}&lt;/code&gt; only appends the relative path to the &lt;code&gt;STATIC_URL&lt;/code&gt;, which is not sufficient for email clients to locate the image.&lt;/p&gt;
&lt;h2 id="solution-generating-full-urls-in-the-view-with-code-snippets"&gt;Solution - Generating Full URLs in the View (with code snippets)&lt;/h2&gt;
&lt;p&gt;The solution I found was to generate the full URL in the view and pass it as a context variable to the template.&lt;/p&gt;
&lt;p&gt;This involves combining the site's domain with the static file path. This approach uses &lt;code&gt;get_current_site&lt;/code&gt; to fetch the 
current site's domain and &lt;code&gt;static&lt;/code&gt; to get the static file path, concatenating these to form a complete URL.&lt;/p&gt;
&lt;h3 id="in-the-view"&gt;In the view&lt;/h3&gt;
&lt;p&gt;This is an example code to demonstrate how to create the full URL in a Django view:&lt;/p&gt;
&lt;p&gt;This URL is then passed to the email template context and used in the src attribute of the img tag.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Please note that you need to adapt the paths to your project.&lt;/strong&gt;&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code literal-block"&gt;&lt;span class="c1"&gt;# in views.py&lt;/span&gt;

&lt;span class="c1"&gt;# imports we need to create the full URL&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nn"&gt;django.contrib.sites.shortcuts&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;get_current_site&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nn"&gt;django.templatetags.static&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;static&lt;/span&gt;

&lt;span class="c1"&gt;# imports we need to render the template to use in the email&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nn"&gt;django.template.loader&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;render_to_string&lt;/span&gt;

&lt;span class="c1"&gt;# imports we need to send the email&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nn"&gt;django.core.mail&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;send_mail&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;my_view&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="c1"&gt;# or any other view&lt;/span&gt;
    &lt;span class="c1"&gt;# we get the current site to get the domain&lt;/span&gt;
    &lt;span class="n"&gt;current_site&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;get_current_site&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c1"&gt;# we get the static file path and concatenate it with the domain&lt;/span&gt;
    &lt;span class="n"&gt;logo_url&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="s1"&gt;'https://&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;current_site&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;domain&lt;/span&gt;&lt;span class="si"&gt;}{&lt;/span&gt;&lt;span class="n"&gt;static&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"images/your-logo.png"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s1"&gt;'&lt;/span&gt;

    &lt;span class="c1"&gt;# we generate a context with the variables we want to use in the template&lt;/span&gt;
    &lt;span class="n"&gt;context&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="s1"&gt;'logo_url'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;logo_url&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="c1"&gt;# ... other context variables ...&lt;/span&gt;
                &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="n"&gt;subject&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'Subject of your email'&lt;/span&gt;

    &lt;span class="c1"&gt;# we render the templates to use in the email&lt;/span&gt;
    &lt;span class="n"&gt;message_plain&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;render_to_string&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'my_template.txt'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;message_html&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;render_to_string&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'my_template.html'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="n"&gt;email&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'test@example.com'&lt;/span&gt;

    &lt;span class="c1"&gt;# we send the email&lt;/span&gt;
    &lt;span class="n"&gt;send_mail&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;subject&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;message_plain&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;email&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;html_message&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;message_html&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;h3 id="in-the-templates"&gt;In the templates&lt;/h3&gt;
&lt;p&gt;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.&lt;/p&gt;
&lt;h4 id="html-template"&gt;HTML template&lt;/h4&gt;
&lt;div class="code"&gt;&lt;pre class="code literal-block"&gt;&lt;span class="cm"&gt;&amp;lt;!-- in my_template.html --&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;img&lt;/span&gt; &lt;span class="na"&gt;src&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"{{ logo_url }}"&lt;/span&gt; &lt;span class="na"&gt;alt&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"Your Logo"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;h4 id="plain-text-template"&gt;Plain text template&lt;/h4&gt;
&lt;p&gt;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.&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code literal-block"&gt;&lt;span class="x"&gt;&amp;lt;!-- in my_template.txt --&amp;gt;&lt;/span&gt;
&lt;span class="x"&gt;Your Logo: &lt;/span&gt;&lt;span class="cp"&gt;{{&lt;/span&gt; &lt;span class="nv"&gt;logo_url&lt;/span&gt; &lt;span class="cp"&gt;}}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;h2 id="keep-in-mind"&gt;Keep in mind&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;This approach is not limited to images. You can use it to generate full URLs for any static file.&lt;/li&gt;
&lt;li&gt;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.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="key-takeaways"&gt;Key Takeaways&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Django's &lt;code&gt;{% static %}&lt;/code&gt; template tag only generates a relative URL, which is not sufficient for email clients to locate the image.&lt;/li&gt;
&lt;li&gt;To generate a full URL for a static file, you need to combine the site's domain with the static file path.&lt;/li&gt;
&lt;li&gt;You can use &lt;code&gt;get_current_site&lt;/code&gt; to fetch the current site's domain and &lt;code&gt;static&lt;/code&gt; to get the static file path, concatenating these to form a complete URL.&lt;/li&gt;
&lt;li&gt;You can use this approach to generate full URLs for any static file in any context and render the templates.&lt;/li&gt;
&lt;li&gt;You construct the full URL in the view and pass it as a context variable to the template.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Happy coding! &lt;/p&gt;
&lt;h2 id="references"&gt;References&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://docs.djangoproject.com/en/4.2/ref/contrib/staticfiles/"&gt;Django Documentation - Managing static files&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.djangoproject.com/en/4.2/ref/contrib/sites/#get-current-site-shortcut"&gt;Django Documentation - get_current_site&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.djangoproject.com/en/4.2/ref/templates/builtins/#static"&gt;Django Documentation - static&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.djangoproject.com/en/4.2/topics/email/#send-mail"&gt;Django Documentation - send_mail&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.djangoproject.com/en/4.2/topics/templates/#django.template.loader.render_to_string"&gt;Django Documentation - render_to_string&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.djangoproject.com/en/4.2/topics/email/#django.core.mail.EmailMessage"&gt;Django Documentation - EmailMessage&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description><category>django</category><category>email</category><category>static files</category><category>templates</category><guid>sending-emails-static-images-django</guid><pubDate>Tue, 09 Jan 2024 08:00:00 GMT</pubDate></item></channel></rss>