djangodjango-formsdjango-email

Receiving email content with in a template using Django contact form


I have set up a fully operational contact form and now I would like to render the users inputs into a html template, so when I receive the email it is easier to read.

How do I do this? Do I link the template below some where, or link the form with in a template? Thank you in advance

def contactPage(request):
    if request.method == 'POST':
        form = contactForm(request.POST)
        if form.is_valid():
            subject = "INQUIRY" 
            body = {
            'full_name': form.cleaned_data['full_name'], 
            'email': form.cleaned_data['email_address'], 
            'message':form.cleaned_data['message'], 
            }
            message = "\n".join(body.values())

            try:
                send_mail(subject, message, '', ['email]) 
            except BadHeaderError:
                return HttpResponse('Invalid header found.')
            return redirect ('thankyou')
      
    form = contactForm()
    return render(request, "contact.html", {'form':form})

Solution

  • One approach is to use the html_message parameter in send_mail(). html_message can refer to an html template that will be used to present the message content. Here's what I have working:

    forms.py

    from django import forms
    
    class ContactForm(forms.Form):
        full_name = forms.CharField(max_length=100)
        message = forms.CharField(widget=forms.Textarea)
        from_email = forms.EmailField()
    

    views.py

    from django.core.mail import send_mail
    from django.http import HttpResponseRedirect
    from django.shortcuts import render
    from django.template.loader import render_to_string
    from django.urls import reverse
    
    from app1.forms import ContactForm
    
    def html_email_view(request):
        template = 'email_form.html'
    
        if request.POST:
            form = ContactForm(request.POST)
    
            if form.is_valid():
                message_plain = render_to_string(
                    'email.txt', 
                    {
                        'full_name': form.cleaned_data['full_name'],
                        'message': form.cleaned_data['message'],
                    },
                )
                message_html = render_to_string(
                    'email.html', 
                    {
                        'full_name': form.cleaned_data['full_name'],
                        'message_lines': list(filter(bool, form.cleaned_data['message'].splitlines())),
                    },
                )            
                send_mail(
                    subject='INQUIRY',
                    message=message_plain,
                    from_email=form.cleaned_data['from_email'],
                    recipient_list=['fake@email.com'],
                    html_message=message_html,
                )
    
                return HttpResponseRedirect(reverse('app1:html_email_view'))
    
        else:
            form = ContactForm()
    
        context = {'form': form}
    
        return render(request, template, context)
    

    email.html

    <h1>You've received an email through site.com!</h1>
    <div><b>Full name:</b> {{ full_name }}</div>
    <hr>
    <div><b>Message:</b></div>
    
    {% for line in message_lines %}
    <p>{{ line }}</p>
    {% endfor %}
    

    email.txt

    Message from: {{ full_name }}
    --------------------------------
    Message:
    {{ message }}
    --------------------------------
    

    Sending a message through this form, I get one email in my inbox. Here's a screen shot: enter image description here

    A related SO question is: Creating email templates with Django

    Note: My answer implements andilabs's answer from that post.

    Docs reference: https://docs.djangoproject.com/en/4.1/topics/email/#send-mail