Spam-resistant contact form

Submitting the form now returns a 302 mailto: redirect, which should
open the user's email client with a pre-composed email. In case it
doesn't work, the example form view now renders text content where
{{ section.href }} should be mentioned as an alternative.

Of course, publishing an email address on the internet will still lead
to spam, but at least Django won't be the one sending it.
main
Jaap Joris Vens 2022-12-25 01:10:41 +01:00
rodzic 347ee7ac3b
commit 1fda2f40c1
4 zmienionych plików z 25 dodań i 23 usunięć

Wyświetl plik

@ -1,6 +1,7 @@
from urllib.parse import quote
from django import forms
from django.conf import settings
from django.core.mail import EmailMessage
from django.utils.translation import gettext_lazy as _
from . import registry
@ -112,24 +113,19 @@ class SectionForm(forms.ModelForm):
class ContactForm(forms.Form):
sender = forms.EmailField(label=_("Your email address"))
spam_protection = forms.CharField(label=_("Your message"), widget=forms.Textarea())
message = forms.CharField(
label=_("Your message"), widget=forms.Textarea(), initial="Hi there!"
"""
Spam-resistant contact form.
"""
body = forms.CharField(
label=_("Your message"), widget=forms.Textarea(), required=False
)
def save(self):
body = self.cleaned_data.get("spam_protection")
if len(body.split()) < 7:
return
spamcheck = self.cleaned_data.get("message")
if spamcheck != "Hi there!":
return
def save(self, address):
"""
Return a mailto: link.
"""
email = EmailMessage(
to=settings.DEFAULT_TO_EMAIL,
body=body,
subject=_("Contact form"),
headers={"Reply-To": self.cleaned_data.get("sender")},
)
email.send()
subject = quote(settings.CONTACT_FORM_EMAIL_SUBJECT, safe="")
body = quote(self.cleaned_data.get("body"), safe="")
return f"mailto:{address}?subject={subject}&body={body}"

Wyświetl plik

@ -107,6 +107,7 @@ class PageView(detail.DetailView):
view = registry.get_view(section, request)
form = view.get_form(method="post")
if form.is_valid():
view.object = section
return view.form_valid(form)
section.invalid_form = form

Wyświetl plik

@ -7,9 +7,9 @@ PROJECT_NAME = os.path.basename(os.path.dirname(os.path.abspath(__file__)))
DEBUG = "runserver" in sys.argv
KEYFILE = f"/tmp/{PROJECT_NAME}.secret"
ADMINS = [("JJ Vens", "jj@rtts.eu")]
ADMINS = [("Jaap Joris Vens", "jj@rtts.eu")]
DEFAULT_FROM_EMAIL = "noreply@rtts.eu"
DEFAULT_TO_EMAIL = ["jj@rtts.eu"]
CONTACT_FORM_EMAIL_SUBJECT = "Contact form"
ALLOWED_HOSTS = ["*"]
ROOT_URLCONF = PROJECT_NAME + ".urls"
WSGI_APPLICATION = PROJECT_NAME + ".wsgi.application"

Wyświetl plik

@ -1,6 +1,7 @@
from cms.decorators import section_view
from cms.forms import ContactForm
from cms.views import SectionFormView, SectionView
from django.http import HttpResponse
from django.utils.translation import gettext_lazy as _
@ -28,7 +29,11 @@ class Video(SectionView):
@section_view
class Contact(SectionFormView):
verbose_name = _("Contact")
fields = []
fields = ["content", "href"]
form_class = ContactForm
success_url = "/thanks/"
template_name = "contact.html"
def form_valid(self, form):
response = HttpResponse(status=302)
response["Location"] = form.save(self.object.href)
return response