From 3855da21bf386c821a879339cf55bb2a0094e392 Mon Sep 17 00:00:00 2001 From: Serafeim Papastefanos Date: Sat, 22 Mar 2014 09:40:40 +0200 Subject: [PATCH] Add metaclass for AbstractForm and validate ... FormEmailProcessor. The metaclass is used to add each non-abstract form in a registry in a similar way as for Pages. It also checks if an form_processing_backend is defined and if it is it will call its validate_usage method. This way, the validate_usage method can throw immediately and ImproperlyConfigured method so the developer would know if he's done something wrong. The validate_usage method of the FormEmailProcessor has been implemented this way. --- wagtail/wagtailforms/backends/email.py | 10 ++++-- wagtail/wagtailforms/models.py | 49 +++++++++++++++++++++----- 2 files changed, 48 insertions(+), 11 deletions(-) diff --git a/wagtail/wagtailforms/backends/email.py b/wagtail/wagtailforms/backends/email.py index ec1677318..063a2ce65 100644 --- a/wagtail/wagtailforms/backends/email.py +++ b/wagtail/wagtailforms/backends/email.py @@ -9,9 +9,15 @@ class EmailFormProcessor(BaseFormProcessor): def __init__(self): pass + @staticmethod def validate_usage(page): - return True + try: + page._meta.get_field('subject') + page._meta.get_field('to_address') + page._meta.get_field('from_address') + except: + raise ImproperlyConfigured("To use the EmailFormProcessor your Page must define the fields: subject, to_address and from_address.") def process(self, page, form): content = ', '.join([ x[1].label +': '+ form.data.get(x[0]) for x in form.fields.items() ]) - tasks.send_email_task.delay("New " + page.title+" form submission at " + str(datetime.datetime.now()) , content, page.email_from, [page.email_to] ) + tasks.send_email_task.delay(page.subject, content, [page.to_address], page.from_address, ) diff --git a/wagtail/wagtailforms/models.py b/wagtail/wagtailforms/models.py index 9eed4f61b..f64f56df7 100644 --- a/wagtail/wagtailforms/models.py +++ b/wagtail/wagtailforms/models.py @@ -1,4 +1,6 @@ + from django.conf import settings +from django.contrib.contenttypes.models import ContentType from django.db import models from django.shortcuts import render from django.utils.translation import ugettext_lazy as _ @@ -6,7 +8,7 @@ from django.utils.translation import ugettext_lazy as _ import json import re -from wagtail.wagtailcore.models import Page, Orderable +from wagtail.wagtailcore.models import PageBase, Page, Orderable from wagtail.wagtailadmin.edit_handlers import FieldPanel, InlinePanel from wagtail.wagtailforms.backends.email import EmailFormProcessor @@ -66,11 +68,39 @@ class AbstractFormFields(models.Model): abstract = True +FORM_MODEL_CLASSES = [] +_FORM_CONTENT_TYPES = [] + +def get_form_types(): + global _FORM_CONTENT_TYPES + if len(_FORM_CONTENT_TYPES) != len(FORM_MODEL_CLASSES): + _FORM_CONTENT_TYPES = [ + ContentType.objects.get_for_model(cls) for cls in FORM_MODEL_CLASSES + ] + return _FORM_CONTENT_TYPES + + +class FormBase(PageBase): + """Metaclass for Forms""" + def __init__(cls, name, bases, dct): + super(FormBase, cls).__init__(name, bases, dct) + + if not cls.is_abstract: + # register this type in the list of page content types + FORM_MODEL_CLASSES.append(cls) + # Check if form_processing_backend is ok + if hasattr(cls, 'form_processing_backend'): + cls.form_processing_backend.validate_usage(cls) + + class AbstractForm(Page): """A Form Page. Pages implementing a form should inhert from it""" + + __metaclass__ = FormBase + form_builder = FormBuilder is_abstract = True # Don't display me in "Add" - + def __init__(self, *args, **kwargs): super(AbstractForm, self).__init__(*args, **kwargs) if not hasattr(self, 'landing_page_template'): @@ -118,17 +148,18 @@ class AbstractForm(Page): class AbstractEmailForm(AbstractForm): - """A Form Page that sends email. Pages implementing a form that should be send to an email should inhert from it""" + """A Form Page that sends email. Pages implementing a form to be send to an email should inherit from it""" is_abstract = True # Don't display me in "Add" form_processing_backend = EmailFormProcessor - - email_to = models.CharField(max_length=255, ) - email_from = models.CharField(max_length=255, ) - + + to_address = models.CharField(max_length=255, ) + from_address = models.CharField(max_length=255, blank=True) + subject = models.CharField(max_length=255, ) + class Meta: abstract = True - - + + ######## TEST class ConcreteFormFields(Orderable, AbstractFormFields): page = ParentalKey('wagtailforms.ConcreteForm', related_name='form_fields')