1

I know that there have been questions like this on the site, but none of them have been able to answer my difficulty. So I have the code as following:

# custom_methods.py

from django.core.mail import EmailMultiAlternatives
from django.conf import settings

from pathlib import Path
from email.mime.image import MIMEImage

import threading, random, os

class EmailThread(threading.Thread):
    def __init__(self, subject, body, from_email, recipient_list, fail_silently, html):
        self.subject = subject
        self.body = body
        self.from_email = from_email
        self.recipient_list = recipient_list
        self.fail_silently = fail_silently
        self.html = html
        threading.Thread.__init__(self)

    def run(self):
        msg = EmailMultiAlternatives(self.subject, self.body, self.from_email, self.recipient_list)
        image_path = os.path.join(settings.BASE_DIR, '/static/images/instagram_icon.png')
        image_name = Path(image_path).name
        if self.html:
            msg.attach_alternative(self.html, "text/html")
            msg.content_subtype = 'html'
            msg.mixed_subtype = 'related'

            with open(image_path, 'rb') as f:
                image = MIMEImage(f.read())
                image.add_header('Content-ID', f"<{image_name}>")
                msg.attach(image)
        msg.send(self.fail_silently)

def send_mail(subject, recipient_list, body='', from_email=settings.EMAIL_HOST_USER, fail_silently=False, html=None, *args, **kwargs):
    EmailThread(subject, body, from_email, recipient_list, fail_silently, html).start()
# views.py

class UserRegisterView(CreateView):
    model = User
    form_class = CustomUserCreationForm
    template_name = 'accounts/register.html'

    def form_valid(self, form):
        self.object = form.save(commit=False)
        self.object.is_active = False
        self.object.save()
        send_mail(
            subject=f'{self.object.code} is your Instagram code',
            recipient_list=[self.object.email],
            html=render_to_string('accounts/register_email.html', {
                'email':self.object.email,
                'code':self.object.code,
            })
        )
        return redirect('accounts:login')
# register_email.html - This is the html that is connected to the email that will be sent

{% load static %}
{% load inlinecss %}

{% inlinecss "css/email.css" %}
<img src="cid:{image_name}">                    

<h1>Hi,</h1>
<h2>Someone tried to sign up for an Instagram account with {{ email }}. If it was you, enter this confirmation code in the app:</h2>
<h2>{{ code }}</h2>
{% endinlinecss %}

So what suppose to happen is the following:

  1. Register the user
  2. When the user is registered, an email is sent to the user with the html template I've shown above.

Now everything works fine, but it goes wrong when I register the user, and in the Powershell, the following error pops:

with open(image_path, 'rb') as f:
FileNotFoundError: [Errno 2] No such file or directory: 'C:/static/images/instagram_icon.png'

Of course the image cannot be found in the 'C:/static/images/instagram_icon.png', because the absolute directory of the image would be in 'C:Users/...(and so on).../static/images/instagram_icon.png'. Then how do I fix this problem in the development stage? I couldn't find the answer for this and can anybody help??

Sihwan Lee
  • 179
  • 2
  • 10
  • Remove the leading slash before static, i.e., `image_path = os.path.join(settings.BASE_DIR, 'static/images/instagram_icon.png')`. Print the output with and without the leading slash to see the difference. –  Dec 16 '20 at 14:21
  • @JustinEzequiel well the image is attached as an attachment, but I can't see it as embedded on the email – Sihwan Lee Dec 16 '20 at 14:25
  • Well, that's what `msg.attach(image)` does. My comment above was just to solve your `FileNotFoundError` error. –  Dec 16 '20 at 14:28
  • @norok2 This didn't help – Sihwan Lee Dec 16 '20 at 14:30
  • 1
    For embedding the image, see https://stackoverflow.com/questions/8499633/how-to-display-base64-images-in-html for ideas. –  Dec 16 '20 at 14:30
  • @JustinEzequiel Thanks for the idea, although that doesn't work either – Sihwan Lee Dec 16 '20 at 14:37
  • 1
    You should probably be more specific in what ways the suggestion(s) "did not work". Besides, embedding must work because you would create a stand-alone HTML file. – norok2 Dec 16 '20 at 14:48
  • Update your question with the new code you've tried. –  Dec 17 '20 at 00:54
  • @norok2 Embedding the image as a base64 encode works in a single HTML file, but the image does not show up as an email html template when I look at the email with the same HTML template that's been sent to me by the Django SMTP. That's why I said it doesn't work. – Sihwan Lee Dec 17 '20 at 03:59

0 Answers0