There are two contact-form classes included in django-contact-form; one provides all the infrastructure for a contact form, and will usually be the base class for subclasses which want to extend or modify functionality. The other is a subclass which adds spam filtering to the contact form.
The base contact form class from which all contact form classes should inherit.
If you don't need any customization, you can use this form to provide basic contact-form functionality; it will collect name, email address and message.
The ~contact_form.views.ContactFormView
included in this application knows how to work with this form and can handle many types of subclasses as well (see below for a discussion of the important points), so in many cases it will be all that you need. If you'd like to use this form or a subclass of it from one of your own views, here's how:
- When you instantiate the form, pass the current
~django.http.HttpRequest
object as the keyword argument request; this is used internally by the base implementation, and also made available so that subclasses can add functionality which relies on inspecting the request (such as spam filtering). - To send the message, call the form's
save
method, which accepts the keyword argument fail_silently and defaults it to False. This argument is passed directly to Django's~django.core.mail.send_mail
function, and allows you to suppress or raise exceptions as needed for debugging. Thesave
method has no return value.
Other than that, treat it like any other form; validity checks and validated data are handled normally, through the ~django.forms.Form.is_valid
method and the ~django.forms.Form.cleaned_data
dictionary.
Under the hood, this form uses a somewhat abstracted interface in order to make it easier to subclass and add functionality.
The following attributes play a role in determining behavior, and any of them can be implemented as an attribute or as a method (for example, if you wish to have from_email
be dynamic, you can implement a method named from_email
instead of setting the attribute from_email
).
from_email
The email address (str
) to use in the From: header of the message. By default, this is the value of the Django setting ~django.conf.settings.DEFAULT_FROM_EMAIL
.
recipient_list
A list
of recipients for the message. By default, this is the email addresses specified in the setting ~django.conf.settings.MANAGERS
.
subject_template_name
A str
, the name of the template to use when rendering the subject line of the message. By default, this is contact_form/contact_form_subject.txt.
template_name
A str
, the name of the template to use when rendering the body of the message. By default, this is contact_form/contact_form.txt.
And two methods are involved in producing the contents of the message to send:
message
Returns the body of the message to send. By default, this is accomplished by rendering the template name specified in template_name
.
- rtype
str
subject
Returns the subject line of the message to send. By default, this is accomplished by rendering the template name specified in subject_template_name
.
- rtype
str
Warning
Subject must be a single line
The subject of an email is sent in a header (named Subject:). Because email uses newlines as a separator between headers, newlines in the subject can cause it to be interpreted as multiple headers; this is the header injection attack. To prevent this, subject
will always force the subject to a single line of text, stripping all newline characters. If you override subject
, be sure to either do this manually, or use super
to call the parent implementation.
Finally, the message itself is generated by the following two methods:
get_message_dict
This method loops through from_email
, recipient_list
, message
and subject
, collecting those parts into a dictionary with keys corresponding to the arguments to Django's send_mail function, then returns the dictionary. Overriding this allows essentially unlimited customization of how the message is generated. Note that for compatibility, implementations which override this should support callables for the values of from_email
and recipient_list
.
- rtype
dict
get_context
For methods which render portions of the message using templates (by default, message
and subject
), generates the context used by those templates. The default context will be a ~django.template.RequestContext
(using the current HTTP request, so user information is available), plus the contents of the form's ~django.forms.Form.cleaned_data
dictionary, and one additional variable:
- site
If django.contrib.sites is installed, the currently-active
~django.contrib.sites.models.Site
object. Otherwise, a~django.contrib.sites.requests.RequestSite
object generated from the request.
- rtype
dict
Meanwhile, the following attributes/methods generally should not be overridden; doing so may interfere with functionality, may not accomplish what you want, and generally any desired customization can be accomplished in a more straightforward way through overriding one of the attributes/methods listed above.
request
The ~django.http.HttpRequest
object representing the current request. This is set automatically in __init__(), and is used both to generate a ~django.template.RequestContext
for the templates and to allow subclasses to engage in request-specific behavior.
save
If the form has data and is valid, will send the email, by calling get_message_dict
and passing the result to Django's ~django.core.mail.send_mail
function.
Note that subclasses which override __init__ or save
need to accept *args and **kwargs, and pass them via super
, in order to preserve behavior (each of those methods accepts at least one additional argument, and this application expects and requires them to do so).
The Akismet (spam-filtering) contact form class
A subclass of ContactForm
which adds spam filtering, via the Wordpress Akismet spam-detection service.
Use of this class requires you to provide configuration for the Akismet web service; you'll need to obtain an Akismet API key, and you'll need to associate it with the site you'll use the contact form on. You can do this at <https://akismet.com/>. Once you have, you can configure in either of two ways:
- Put your Akismet API key in the Django setting
~django.conf.settings.AKISMET_API_KEY
, and the URL it's associated with in the setting~django.conf.settings.AKISMET_BLOG_URL
, or - Put your Akismet API key in the environment variable PYTHON_AKISMET_API_KEY, and the URL it's associated with in the environment variable PYTHON_AKISMET_BLOG_URL.
You will also need the Python Akismet module to communicate with the Akismet web service. You can install it by running pip install akismet, or django-contact-form can install it automatically for you if you run pip install django-contact-form[akismet].
Once you have an Akismet API key and URL configured, and the akismet module installed, you can drop in AkismetContactForm
anywhere you would have used ContactForm
. A URLconf is provided in django-contact-form, at contact_form.akismet_urls, which will correctly configure AkismetContactForm
for you.