Activate account HTML email in Django

I have a Django App that lets users to register to the system. After the user register via a form receive a email with an activation link. The app works very well, but I want to send the user an HTML mail, not only plain text. I use an template to provide fields to be filled. The problem I face is how to provide the uuid and token in an HTML template in an activate link.

I've reading about the send_mail() function, but I don't understand how to use for my purpose.

I'm using Django 3.2.8.

Show my code:

myApp/urls.py

path('registro/<str:usuario>', views.registro, name='registro'),
path('activate/<uidb64>/<token>/', views.activate, name='activate'),    
path('esperaconfirmacionregistro/', views.esperaConfirmacionRegistro, name='esperaconfirmacionregistro'),
path('confirmacionregistro/<str:status>', views.confirmacionRegistro, name='confirmacionregistro'),

acc_active_email.html

{% autoescape off %}  

Saludos, {{user.first_name}} {{user.last_name}}.

Por favor da click en el enlace para confirmar tu registro, 
http://{{ domain }}{% url 'activate' uidb64=uid token=token %}  
{% endautoescape %}

views.py

def registro(request,usuario):

    if request.method == 'POST':
        
        form = FormularioAutoRegistro(request.POST, initial={'usuario':usuario})
        if form.is_valid():

            user = form.save()  

            current_site_info = get_current_site(request)  
            mail_subject = 'Activar cuenta de usuario'  
            message = render_to_string('myApp/acc_active_email.html', {  
                'user': user,  
                'domain': current_site_info.domain,  
                'uid': urlsafe_base64_encode(force_bytes(user.pk)),
                'token': account_activation_token.make_token(user),  
            })
            to_email = form.cleaned_data.get('email')  

            email = EmailMessage(mail_subject, message, to=[to_email])  
            email.send()  

            form = FormularioAutoRegistro(initial={'usuario':''})   
            return redirect('esperaconfirmacionregistro') 
            
    else:
        form = FormularioAutoRegistro(initial={'usuario':usuario})
        return render(request, 'myApp/registro.html', {'form': form})

def activate(request, uidb64, token):  
    user = get_user_model()  
    try:  
        uid = force_text(urlsafe_base64_decode(uidb64))  
        user = customuser.objects.get(pk=uid)  
    except(TypeError, ValueError, OverflowError, user.DoesNotExist):  
        user = None  
    
    if user is not None and account_activation_token.check_token(user, token):  
        user.is_active = True  
        user.save()  
        return redirect('confirmacionregistro', status='confirm') 
    else:  
        return redirect('confirmacionregistro', status='fail')  

def confirmacionRegistro(request, status):

    titulo = ''
    mensaje = ''

    if status=='confirm':
        titulo = 'Cuenta confirmada'
        mensaje = 'Gracias por confirmar tu email.'
    elif status=='fail':
        titulo = 'Link inválido'
        mensaje = 'El link de activación es inválido.'
    else:
        raise Http404

    return render (request,'myApp/confirmacionregistro.html', {'titulo':titulo, 'mensaje':mensaje})


def esperaConfirmacionRegistro(request):
    mensaje = "Autorización pendiente"
    return render(request, 'myApp/esperaconfirmacionregistro.html', {'mensaje': mensaje})

Try using EmailMultiAlternatives instead of EmailMessage. It is pretty similar:

from django.core.mail import EmailMultiAlternatives
mail = EmailMultiAlternatives("title", "content", "email_from@test.pl", ["email_to@test.pl"])

Then you can attach html "alternative":

from django.urls import reverse
url = reverse('activate', kwargs={'uidb64': your_uidb64, 'token': your_token})
html_content = f"Link: <a href='{url}'>{url}</a>"
mail.attach_alternative(html_content, "text/html")

And send it:

mail.send()

Finally I resove my problem. NixonSparrow you are right, I had the answer:

def registro(request,usuario):

    if request.method == 'POST':
        
        form = FormularioAutoRegistro(request.POST, initial={'usuario':usuario})
        if form.is_valid():

            user = form.save()  

            current_site_info = get_current_site(request) 
            mail_subject = 'Activar cuenta de usuario'  
            to_email = form.cleaned_data.get('email')     
            nombre = user.first_name
            apellidos = user.last_name
            domain = current_site_info.domain
            uid = urlsafe_base64_encode(force_bytes(user.pk))
            token = account_activation_token.make_token(user)  
            url = f"http://{domain}/activate/{uid}/{token}"

            content = f"Hola {nombre} {apellidos} \n" \
                      f"Por favor da click en el enlace o copialo y pégalo en el navegador para confirmar tu registro en el sistema: {url} \n" \
                      f"Gracias."
            email = EmailMultiAlternatives(mail_subject, content, "pepe.eloy@gmail.com", [to_email])

            html_content = f"Hola <strong>{nombre} {apellidos}</strong>. <br> <br>" \
                           f"Por favor da click en el enlace para confirmar tu registro en el sistema: <a href='{url}'>{url}</a> <br> <br>" \
                           f"Gracias."
            email.attach_alternative(html_content, "text/html")

            email.send()  

            form = FormularioAutoRegistro(initial={'usuario':''})  
            return redirect('esperaconfirmacionregistro') 
            
    else:
        
        form = FormularioAutoRegistro(initial={'usuario':usuario})

        return render(request, 'myApp/registro.html', {'form': form})
 
Back to Top