Source

django-contact-forms / contactforms / forms.py

from form_utils.forms import BetterForm

class ContactForm(BetterForm):
	"""
	Form object for contactforms
	"""
	def __init__(self, request = None):
		if request is not None and request.method == "POST":
			super(BetterForm, self).__init__(request.POST)
		else:
			super(BetterForm, self).__init__()
		self._request = request

	@staticmethod
	def create(name, data):
		"""
		Static method to create a dynamic ContactForm class
		based on user provided yaml settings.
		"""
		base_form_fields = {}
		for i in data['items']:
			base_form_fields[i['id']] = yaml_to_field(i)
		
		fieldsets = []
		for i, v in enumerate(data['fieldsets']):
			fieldsets.append((v.get('legend', str(i)).lower(), v))
		meta = {
			'fieldset': fieldsets,
		}
		base_form_fields['Meta'] = type('Meta', (), meta)
		
		form = type(
			'contact_form_'+name,
			(ContactForm,),
			base_form_fields
		)
		return form

class FieldRegistry(object):
	"""
	Module-level registry to map text-labels (as defined
	in yaml) to actual *Field classes.

	Use FieldRegistry('label', field_cls) to associate
	your own custom field class with a particular label.
  (You probably want to do that in your models.py file)
	"""
	registry = {}

	@classmethod
	def register(cls, k, v):
		cls.registry[k] = v

	@classmethod
	def get(cls, name, *args, **kwargs):
		ret_cls = cls.registry[name]
		ret = ret_cls(*args, **kwargs)
		return ret

def yaml_to_field(data):
	_type = data['type']
	kwargs = dict((k,v) for k,v in data.items() if k not in ('id', 'type', 'autofocus', 'attrs'))
	if 'required' not in kwargs:
		kwargs['required'] = False
	ret = FieldRegistry.get(_type, **kwargs)
	if data.get('autofocus') is True:
		ret.widget.attrs.update({'autofocus': 'autofocus'})
	for k,v in data.get('attrs', {}).iteritems():
		ret.widget.attrs.update({k: v})
	return ret