2. Basics
● Validate user input
● Convert to internal representation
● Render forms, display validation error
● Work with nested data structures
3. Abstraction layers
❏ Form
❏ Field (+ FieldSet, FieldList, FieldBlock)
❏ Converter
❏ Widget
❏ permissions (rw)
❏ raw and clean values
4. Forms
class UncleForm(Form):
fields = [
Field('name'),
FieldList('nephews', field=FieldSet(None, fields=[
Field('name'),
])),
]
def process_form(env):
form = UncleForm(env, initial=init)
if form.accept(env.request.POST):
data = form.python_data
else:
errors = form.errors
{"name": "Scrooge",
"nephews": [{"name": "Huey"},
{"name": "Dewey"},
{"name": "Louie"}]}
{"name": "Required field"}
webob.Request.GET or any
MultiDict/dict
Nested data structure
Form subclass with defined fields
5. Converters and validators
class Int(Converter):
def to_python(self, val):
if val == '':
return None
try:
return int(val)
except ValueError:
raise ValidationError(error_msg)
def from_python(self, val):
return unicode(val) if val is not None else ''
def validate(conv, value):
if not check(value):
raise ValidationError(error_msg)
return value.strip()
function for extra
validation and cleaning
can do additional one-way convertation
errors are written into form.errors
converts value to a string which is
included to raw_data MultiDict
Converts string (dict for FieldSet, list for FieldList) to python
object of target type
6. Converters usage
field1 = Field('id', conv=Int(num_limit(0,10), positive, require=True))
field2 = Field('ids', conv=ListOf(Int()))
field3 = Field('name', conv=ListOf(EnumChoice(choices=[(val, label), ..])))
field4 = field3(conv=field3.conv(required=True))
model_f = FieldSet('user',
conv=convs.ModelChoice(model=User),
fields=[Field('id', conv=Int()),
Field('name')])
Converts a dict
result of FieldSet
to sqlalchemy object
validators
Fields, converters, widgets are easy
to copy and tweak
is included to raw_data MultiDict
Converter
ids=1&ids=2 => {"ids" [1, 2]}
check if value is not empty
after convertation
multiple select
7. Widgets
Responsible for visual representation of an item
field1 = Field('id',
conv=Int(),
widget=TextInput(),
label='Id')
field3 = Field('options',
conv=ListOf(EnumChoice(choices=[(val, label), ..])),
widget=Select(template='widgets/custom-select.html'),
label='Options')
{{ form.render() }}
{{ form.get_field('id').widget.render() }}