[Django]-Django – Sending emails using class based view

5👍

Don’t know why you mixed up listview with formview. From your model it’s kind a blog app. Normally in a blog app the articles/posts list page doesn’t contain any form with email field, except for article detail or Contact Us page. I prefer to split it into different class than using mixin.

My answer based on Daniel Greenfeld’s example here with little bit modification.

In yourapp/forms.py:

from crispy_forms.helper import FormHelper
from crispy_forms.layout import Submit
import floppyforms as forms

class ContactForm(forms.Form):

    name = forms.CharField(required=True)
    email = forms.EmailField(required=True)
    subject = forms.CharField(required=True)
    message = forms.CharField(widget=forms.Textarea)

    def __init__(self, *args, **kwargs):
        self.helper = FormHelper()
        self.helper.add_input(Submit('submit', 'Submit'))
        super(ContactForm, self).__init__(*args, **kwargs)

In yourapp/views.py:

from django.views.generic.list import ListView
from django.views.generic.edit import FormView
from django.conf import settings
from django.core.mail import send_mail
from yourapp.models import Post
from yourapp.forms import ContactForm

class PostListView(ListView):

model = Post

def get_context_data(self, **kwargs):
    context = super(ArticleListView, self).get_context_data(**kwargs)
    context['latest_articles'] = Post.objects.all()[:5]
    return context    

class ContactFormView(FormView):

form_class = ContactForm
template_name = "myapp/email_form.html"
success_url = '/email-sent/'

# this is what you want
def form_valid(self, form):
    message = "{name} / {email} said: ".format(
        name=form.cleaned_data.get('name'),
        email=form.cleaned_data.get('email'))
    message += "\n\n{0}".format(form.cleaned_data.get('message'))
    send_mail(
        subject=form.cleaned_data.get('subject').strip(),
        message=message,
        from_email='contact-form@myapp.com',
        recipient_list=[settings.LIST_OF_EMAIL_RECIPIENTS],
    )
    return super(ContactFormView, self).form_valid(form)       

3👍

Have a look at the documentation, check the methods of the FormMixin and pick the one that fits.

form_valid() might be an option.

in python3:

def form_valid(self, form):
    # do your stuff
    # call the parents class method
    return super().form_valid(form)

This is a quite common approach when using class based views. They usually provide a bunch of attributes and methods – sometimes it is enough to just change some attributes, which change the behavior of the methods (e.g. success_url). But often you will need to override some of there methods. It is always a good idea to read their code in this case, cause you need to decide whether you want to call the mixins implementation at the beginning, at the end (as in the example) or if you really want to override it and provide their logic on your own…

Leave a comment