Search code examples
pythondjangobackend

Django doesn't send email


I encountered an issue where Django is not sending emails to the specified email address. I would greatly appreciate your assistance.

views.py

def register(request):
    form = CreateUserForm()

    if request.method == 'POST':
        form = CreateUserForm(request.POST)
        if form.is_valid():
            user = form.save()
            user.is_active = False
            user.save()
            current_site = get_current_site(request)
            subject = 'Account verification email'
            message = render_to_string('account/registration/email-verification.html', {
                'user': user,
                'domain': current_site.domain,
                'uid': urlsafe_base64_encode(force_bytes(user.pk)),
                'token': user_tokenizer_generate.make_token(user),
            })
            print(message)

            user.email_user(subject=subject, message=message)
            return redirect('email-verification-sent')

    context = {'form':form}
    return render(request, 'account/registration/register.html', context=context)


def email_verification(request, uidb64, token):
    unique_id = force_str(urlsafe_base64_decode(uidb64))
    user = User.objects.get(pk=unique_id)
    if user and user_tokenizer_generate.check_token(user, token):
        user.is_active = True
        user.save()
        return redirect('email-verification-success')
    else:
        return redirect('email-verification-failed')

token.py

from django.contrib.auth.tokens import PasswordResetTokenGenerator


class UserVerificationTokenGenerator(PasswordResetTokenGenerator):
    def _make_hash_value(self, user, timestamp):
        user_id = str(user.pk)
        ts = str(timestamp)
        is_active = str(user.is_active)
        return f"{user_id}{ts}{is_active}"

user_tokenizer_generate = UserVerificationTokenGenerator()

settings.py

EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'
EMAIL_HOST = 'smtp.gmail.com'
EMAIL_PORT = '587'
EMAIL_USE_TLS = 'True'

EMAIL_HOST_USER = '[email protected]'
EMAIL_HOST_PASSWORD = 'XXX'

EMAIL_HOST_USER and EMAIL_HOST_PASSWORD are correct I have already tried using SSL instead of TLS, disabling two-factor authentication, and removing the line 'EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'


Solution

  • I send emails in my projects as follows. Maybe it can be useful for you too.

    Step 1 :

    Activate Gmail account for email senders

    The email account used to send emails must have 2-step verification

    Go to the following address to get the password for sending email:

    Gmail Acount > Manage your Google Account > Security > 2-step verification > App passwords

    Create a new app

    Get your 16-digit password

    Step 2 :

    settings.py
    
    EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'
    EMAIL_HOST = 'smtp.gmail.com'
    EMAIL_USE_TLS = True
    EMAIL_PORT = 587
    EMAIL_HOST_USER = ''    # Sender's email
    EMAIL_HOST_PASSWORD = ''    # The password created for the sender's email
    

    Step 3 :

    # utils Package
    # email_server.py
    
    from django.core.mail import send_mail
    from django.template.loader import render_to_string
    from django.utils.html import strip_tags
    from django.conf import settings
    
    
    def send_email(subject, to, context, template_name):
        html_message = render_to_string(template_name, context)
        plain_message = strip_tags(html_message)
        from_email = settings.EMAIL_HOST_USER
        send_mail(subject, plain_message, from_email, [to], html_message=html_message)
    

    Step 4 :

    # views.py
    
    send_email("Email Subject", 'Email recipient', {context}, "template_path")
    

    Attention

    Note that in this method an html file must be created and give this file as "template_path" to this function.


    Also, I have already created an API for sending emails. You can test it or use it.

    You can see the address and how to send an email here.