I put this into a module:# almost literally taken from# http://deformdemo.repoze.org/pyramid_csrf_demo/import deformimport colander@colander.deferreddef deferred_csrf_default(node, kw): request = kw.get('request') csrf_token = request.session.get_csrf_token() return csrf_token@colander.deferreddef deferred_csrf_validator(node, kw): def validate_csrf(node, value): request = kw.get('request') csrf_token = request.session.get_csrf_token() if value != csrf_token: # Where does 'value' come from?!? raise ValueError('Bad CSRF token') return validate_csrfclass CSRFSchema(colander.Schema): csrf = colander.SchemaNode( colander.String(), default = deferred_csrf_default, validator = deferred_csrf_validator, widget = deform.widget.HiddenWidget(), )Then I generate a schema:from .csrf import CSRFSchema...def genPlainSchema(schema, fields): for field in fields: schema.add(genField(field)) # widgets, etc. return schemadef genSubSchema(schema, fields, key): """fields: all fields from the database, key: the current fieldset""" for field in fields: if field.fieldset != key: continue schema.add(genField(field)) return schemadef genSchemaFromFields(fields, fieldsets): schema = CSRFSchema() if len(fieldsets) == 0: result = genPlainSchema(schema, fields) else: for fieldset in fieldsets: label = fieldset.label if not label: label = fieldset.name subschema = colander.SchemaNode(colander.Mapping(), title=label) schema.add(genSubSchema(subschema, fields, fieldset.id).clone()) result = schema return result Then the form generation:... schema = forms.genSchemaFromFields(formfields, groups).bind(request=request) myform = deform.Form(schema, buttons=('submit',), formid = 'newsletter_create_issue.')and the validation:if 'submit' in request.POST: # needs to be guarded against the formid! controls = request.POST.items() # at this point, 'controls' contains the correct values try: appstruct = myform.validate(controls) # raises an exception, but shouldn't except: ...# In