We have a strong basis in place now:
We can now explore some other validators and patterns:
The t3/baseform.py:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 | """Base class for KARL3 forms.
"""
from lxml.html import document_fromstring
from lxml.html import tostring
from time import time
from formencode import Schema
from formencode import Invalid
from copy import deepcopy
# Simulate getting some vocabularies
vocabularies = {
'countries': [
('AT', 'Austria'),
('BE', 'Belgium'),
('CA', 'Canada'),
('DE', 'Germany'),
('ES', 'Estonia'),
('FI', 'Finland'),
('GB', 'Great Britain'),
],
}
# Make some re-usable fields
from formencode import validators
name = validators.UnicodeString(not_empty=True)
age = validators.Int(not_empty=True, max=200, default=93)
country = validators.OneOf([i[0] for i in vocabularies['countries']])
password = validators.UnicodeString(not_empty=True, strip=True, min=8)
password_confirm = validators.UnicodeString(
not_empty=True, strip=True, min=8)
chained_validators = [validators.FieldsMatch(
'password', 'password_confirm')]
class BaseForm(Schema):
submit_name = 'form.submitted'
cancel_name = 'form.cancel'
allow_extra_fields = True
filter_extra_fields = True
def __init__(self):
Schema.__init__(self)
self.defaults = {}
for name, value in self.fields.items():
default = getattr(value, 'default', None)
if default is not None:
self.defaults[name] = value.default
def is_cancelled(self, request):
self.start_time = time()
return request.POST.get(self.cancel_name, False)
def is_submitted(self, request):
return request.POST.get(self.submit_name, False)
def validate(self, fieldvalues):
fielderrors = {}
try:
fieldvalues = self.to_python(fieldvalues)
except Invalid, e:
fielderrors = e.error_dict
return fieldvalues, fielderrors
def merge(self, htmlstring, fieldvalues):
# Merge in field values, either from the default or from what
# they typed in.
form_tree = document_fromstring(htmlstring)
form = form_tree.forms[0]
schema_field_names = self.fields.keys()
for field_name, field_value in fieldvalues.items():
if field_name in schema_field_names:
form.fields[field_name] = unicode(field_value)
merged_form_html = tostring(form)
# Record the elapsed time
self.elapsed = str(1 / (time() - self.start_time))[0:7]
return merged_form_html
def combine_dicts(self, dict1, dict2):
# We often have multiple sources for field values. For
# example, the default defined into the field versus the value
# typed into the request.params. Combine these, with the
# latter taking presence over the former.
fieldvalues = deepcopy(dict1)
for key, value in dict2.items():
fieldvalues[key] = value
return fieldvalues
|
The views at t3/views.py:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 | from repoze.bfg.chameleon_zpt import render_template_to_response
from repoze.bfg.chameleon_zpt import get_template
from repoze.bfg.chameleon_zpt import render_template
from repoze.bfg.view import static
from webob.exc import HTTPFound
from repoze.bfg.url import model_url
from baseform import BaseForm
from baseform import name
from baseform import age
from baseform import country
from baseform import password
from baseform import password_confirm
from baseform import chained_validators
from baseform import vocabularies
from t3.models import Person
from formencode import Invalid
from random import randrange
static_view = static('templates/static')
# Define a form schema, make an instance
class MyInfo(BaseForm):
name = name
age = age
country = country
password = password
password_confirm = password_confirm
chained_validators = chained_validators
myinfo = MyInfo
def list_people_view(context, request):
layout = get_template('templates/layout.pt')
return render_template_to_response(
'templates/list_people.pt',
context = context,
request = request,
page_title='List People',
layout=layout,
)
def add_person_view(context, request):
layout = get_template('templates/layout.pt')
formfields = get_template('templates/formfields.pt')
form = myinfo()
if form.is_cancelled(request):
return HTTPFound(location=model_url(context, request))
if form.is_submitted(request):
fieldvalues = form.combine_dicts(form.defaults, request.POST)
# Now validate
try:
fv = fieldvalues = form.to_python(fieldvalues)
fielderrors = {}
# Go ahead and do the work to add content, etc.
person = Person(fv['name'], fv['age'], fv['country'])
__name__ = str(randrange(0, 99999))
context[__name__] = person
return HTTPFound(location=model_url(person, request))
except Invalid, e:
fielderrors = e.error_dict
else:
fieldvalues = form.defaults
fielderrors = {}
# Render the form and shove some default values in
form_html = render_template(
'templates/myform.pt',
context = context,
request=request,
formfields=formfields,
fielderrors=fielderrors,
vocabularies=vocabularies,
)
rendered_form = form.merge(form_html, fieldvalues)
return render_template_to_response(
'templates/add_person.pt',
context=context,
request = request,
page_title='Add Person',
layout=layout,
form_html=rendered_form,
elapsed=form.elapsed,
)
def show_person_view(context, request):
layout = get_template('templates/layout.pt')
return render_template_to_response(
'templates/show_person.pt',
context = context,
request = request,
page_title='Show Person',
layout=layout,
)
def edit_person_view(context, request):
layout = get_template('templates/layout.pt')
formfields = get_template('templates/formfields.pt')
form = myinfo()
if form.is_cancelled(request):
return HTTPFound(location=model_url(context, request))
if form.is_submitted(request):
fieldvalues = form.combine_dicts(context.__dict__, request.POST)
# Now validate
try:
fieldvalues = form.to_python(fieldvalues)
fielderrors = {}
# Go ahead and do the work to update content, etc.
context.name = fieldvalues['name']
context.age = fieldvalues['age']
context.country = fieldvalues['country']
return HTTPFound(location=model_url(context, request))
except Invalid, e:
fielderrors = e.error_dict
else:
fieldvalues = context.__dict__
fielderrors = {}
# Render the form and shove some default values in
form_html = render_template(
'templates/myform.pt',
request=request,
formfields=formfields,
fielderrors=fielderrors,
vocabularies=vocabularies,
)
rendered_form = form.merge(form_html, fieldvalues)
return render_template_to_response(
'templates/edit_person.pt',
context = context,
request = request,
page_title='Edit %s' % context.name,
layout=layout,
form_html=rendered_form,
elapsed=form.elapsed,
)
|