This forms module is originally derived from Zine project hosted at: http://zine.pocoo.org/
Baseclass for all widgets. All widgets share a common interface that can be used from within templates.
Take this form as an example:
>>> class LoginForm(Form):
... username = TextField(required=True)
... password = TextField(widget=PasswordInput)
... flags = MultiChoiceField(choices=[1, 2, 3])
...
>>> form = LoginForm()
>>> form.validate({'username': '', 'password': '',
... 'flags': [1, 3]})
False
>>> widget = form.as_widget()
You can get the subwidgets by using the normal indexing operators:
>>> username = widget['username']
>>> password = widget['password']
To render a widget you can usually invoke the render() method. All keyword parameters are used as HTML attribute in the resulting tag. You can also call the widget itself (username() instead of username.render()) which does the same if there are no errors for the field but adds the default error list after the widget if there are errors.
Widgets have some public attributes:
errors
gives the list of errors:
>>> username.errors [u'This field is required.']This error list is printable:
>>> print username.errors() <ul class="errors"><li>This field is required.</li></ul>Like any other sequence that yields list items it provides as_ul and as_ol methods:
>>> print username.errors.as_ul() <ul><li>This field is required.</li></ul>Keep in mind that widget.errors() is equivalent to widget.errors.as_ul(class_='errors', hide_empty=True).
value
returns the value of the widget as primitive. For basic widgets this is always a string, for widgets with subwidgets or widgets with multiple values a dict or a list:
>>> username.value u'' >>> widget['flags'].value [u'1', u'3']
name gives you the name of the field for form submissions:
>>> username.name 'username'Please keep in mind that the name is not always that obvious. Zine supports nested form fields so it’s a good idea to always use the name attribute.
id
gives you the default domain for the widget. This is either none if there is no idea for the field or f_ + the field name with underscores instead of dots:
>>> username.id 'f_username'
all_errors
like errors but also contains the errors of child widgets.
A widget that is a HTML input field.
A widget that holds text.
A widget that holds text.
A widget that holds a password.
A hidden input field for text.
Displays a textarea.
A simple checkbox.
A select box.
A radio button in an input group.
A checkbox in an input group.
A group of radio buttons.
A group of checkboxes.
Abstract field base class.
Per default validate if the value is not None. This method is called before the custom validators are applied to not perform validation if the field is empty and not required.
For example a validator like is_valid_ip is never called if the value is an empty string and the field hasn’t raised a validation error when checking if the field is required.
Convert a value into a primitve (string or a list/dict of lists, dicts or strings).
This method must never fail!
Apply a single field to a sequence of values.
>>> field = Multiple(IntegerField())
>>> field([u'1', u'2', u'3'])
[1, 2, 3]
Recommended widgets:
Per default validate if the value is not None. This method is called before the custom validators are applied to not perform validation if the field is empty and not required.
For example a validator like is_valid_ip is never called if the value is an empty string and the field hasn’t raised a validation error when checking if the field is required.
Works like the multiple field but for comma separated values:
>>> field = CommaSeparated(IntegerField())
>>> field(u'1, 2, 3')
[1, 2, 3]
The default widget is a TextInput but Textarea would be a possible choices as well.
Per default validate if the value is not None. This method is called before the custom validators are applied to not perform validation if the field is empty and not required.
For example a validator like is_valid_ip is never called if the value is an empty string and the field hasn’t raised a validation error when checking if the field is required.
Works like CommaSeparated but uses multiple lines:
>>> field = LineSeparated(IntegerField())
>>> field(u'1\n2\n3')
[1, 2, 3]
The default widget is a Textarea and taht is pretty much the only thing that makes sense for this widget.
Per default validate if the value is not None. This method is called before the custom validators are applied to not perform validation if the field is empty and not required.
For example a validator like is_valid_ip is never called if the value is an empty string and the field hasn’t raised a validation error when checking if the field is required.
Field for strings.
>>> field = TextField(required=True, min_length=6)
>>> field('foo bar')
u'foo bar'
>>> field('')
Traceback (most recent call last):
...
ValidationError: This field is required.
Convert a value into a primitve (string or a list/dict of lists, dicts or strings).
This method must never fail!
Convert a value into a primitve (string or a list/dict of lists, dicts or strings).
This method must never fail!
Convert a value into a primitve (string or a list/dict of lists, dicts or strings).
This method must never fail!
Field for datetime objects.
>>> field = DateTimeField()
>>> field('1970-01-12 00:00')
datetime.datetime(1970, 1, 12, 0, 0)
>>> field('foo')
Traceback (most recent call last):
...
ValidationError: Please enter a valid date.
Per default validate if the value is not None. This method is called before the custom validators are applied to not perform validation if the field is empty and not required.
For example a validator like is_valid_ip is never called if the value is an empty string and the field hasn’t raised a validation error when checking if the field is required.
A field that queries for a model.
The first argument is the name of the model. If the key is not given (None) the primary key is assumed. You can specify query parameter on init or anytime you want via set_query() method. It gives you query based option rendering and validation.
Here is an example for setting query after init:
>>> class FormWithModelField(Form):
... model_field = forms.ModelField(model=TestModel, reuired=True)
>>> form = FormWithModelField()
... query = TestModel.all().filter('user =', user.key())
... form.model_field.set_query(query)
If the Model class has __unicode__() method, the return value of this method will be used for rendering the text in an option tag. If there’s no __unicode__() method, Model.__repr__() will be used for this purpose. You can override this behavior by passing an attribute name used for the option tag’s value with option_name keyword argument on initialization of this field.
Per default validate if the value is not None. This method is called before the custom validators are applied to not perform validation if the field is empty and not required.
For example a validator like is_valid_ip is never called if the value is an empty string and the field hasn’t raised a validation error when checking if the field is required.
A hidden field that points to a model identified by primary key. Can be used to pass models through a form.
Per default validate if the value is not None. This method is called before the custom validators are applied to not perform validation if the field is empty and not required.
For example a validator like is_valid_ip is never called if the value is an empty string and the field hasn’t raised a validation error when checking if the field is required.
A field that lets a user select one out of many choices.
A choice field accepts some choices that are valid values for it. Values are compared after converting to unicode which means that 1 == "1":
>>> field = ChoiceField(choices=[1, 2, 3])
>>> field('1')
1
>>> field('42')
Traceback (most recent call last):
...
ValidationError: Please enter a valid choice.
Two values a and b are considered equal if either a == b or primitive(a) == primitive(b) where primitive is the primitive of the value. Primitives are created with the following algorithm:
- if the object is None the primitive is the empty string
- otherwise the primitive is the string value of the object
A choice field also accepts lists of tuples as argument where the first item is used for comparing and the second for displaying (which is used by the SelectBoxWidget):
>>> field = ChoiceField(choices=[(0, 'inactive'), (1, 'active')])
>>> field('0')
0
Because all fields are bound to the form before validation it’s possible to assign the choices later:
>>> class MyForm(Form):
... status = ChoiceField()
...
>>> form = MyForm()
>>> form.status.choices = [(0, 'inactive', 1, 'active')]
>>> form.validate({'status': '0'})
True
>>> form.data
{'status': 0}
If a choice field is set to “not required” and a SelectBox is used as widget you have to provide an empty choice or the field cannot be left blank.
>>> field = ChoiceField(required=False, choices=[('', _('Nothing')),
... ('1', _('Something'))])
Per default validate if the value is not None. This method is called before the custom validators are applied to not perform validation if the field is empty and not required.
For example a validator like is_valid_ip is never called if the value is an empty string and the field hasn’t raised a validation error when checking if the field is required.
Convert a value into a primitve (string or a list/dict of lists, dicts or strings).
This method must never fail!
A field that lets a user select multiple choices.
Per default validate if the value is not None. This method is called before the custom validators are applied to not perform validation if the field is empty and not required.
For example a validator like is_valid_ip is never called if the value is an empty string and the field hasn’t raised a validation error when checking if the field is required.
Field for numbers.
>>> field = IntegerField(min_value=0, max_value=99)
>>> field('13')
13
>>> field('thirteen')
Traceback (most recent call last):
...
ValidationError: Please enter a whole number.
>>> field('193')
Traceback (most recent call last):
...
ValidationError: Ensure this value is less than or equal to 99.
Per default validate if the value is not None. This method is called before the custom validators are applied to not perform validation if the field is empty and not required.
For example a validator like is_valid_ip is never called if the value is an empty string and the field hasn’t raised a validation error when checking if the field is required.
Convert a value into a primitve (string or a list/dict of lists, dicts or strings).
This method must never fail!
Field for integers.
>>> field = IntegerField(min_value=0, max_value=99)
>>> field('13')
13
>>> field('thirteen')
Traceback (most recent call last):
...
ValidationError: Please enter a whole number.
>>> field('193')
Traceback (most recent call last):
...
ValidationError: Ensure this value is less than or equal to 99.
Per default validate if the value is not None. This method is called before the custom validators are applied to not perform validation if the field is empty and not required.
For example a validator like is_valid_ip is never called if the value is an empty string and the field hasn’t raised a validation error when checking if the field is required.
Convert a value into a primitve (string or a list/dict of lists, dicts or strings).
This method must never fail!
Field for floats.
>>> field = IntegerField(min_value=0, max_value=99)
>>> field('13.4')
13.4
>>> field('thirteen')
Traceback (most recent call last):
...
ValidationError: Please enter a float number.
>>> field('193.2')
Traceback (most recent call last):
...
ValidationError: Ensure this value is less than or equal to 99.
Per default validate if the value is not None. This method is called before the custom validators are applied to not perform validation if the field is empty and not required.
For example a validator like is_valid_ip is never called if the value is an empty string and the field hasn’t raised a validation error when checking if the field is required.
Convert a value into a primitve (string or a list/dict of lists, dicts or strings).
This method must never fail!
Field for file upload.
Per default validate if the value is not None. This method is called before the custom validators are applied to not perform validation if the field is empty and not required.
For example a validator like is_valid_ip is never called if the value is an empty string and the field hasn’t raised a validation error when checking if the field is required.
Field for boolean values.
>>> field = BooleanField()
>>> field('1')
True
>>> field = BooleanField()
>>> field('')
False
Per default validate if the value is not None. This method is called before the custom validators are applied to not perform validation if the field is empty and not required.
For example a validator like is_valid_ip is never called if the value is an empty string and the field hasn’t raised a validation error when checking if the field is required.
Form base class.
>>> class PersonForm(Form):
... name = TextField(required=True)
... age = IntegerField()
>>> form = PersonForm()
>>> form.validate({'name': 'johnny', 'age': '42'})
True
>>> form.data['name']
u'johnny'
>>> form.data['age']
42
Let’s cause a simple validation error:
>>> form = PersonForm()
>>> form.validate({'name': '', 'age': 'fourty-two'})
False
>>> print form.errors['age'][0]
Please enter a whole number.
>>> print form.errors['name'][0]
This field is required.
You can also add custom validation routines for fields by adding methods that start with the prefix validate_ and the field name that take the value as argument. For example:
>>> class PersonForm(Form):
... name = TextField(required=True)
... age = IntegerField()
...
... def validate_name(self, value):
... if not value.isalpha():
... raise ValidationError(u'The value must only contain letters')
>>> form = PersonForm()
>>> form.validate({'name': 'mr.t', 'age': '42'})
False
>>> form.errors
{'name': [u'The value must only contain letters']}
You can also validate multiple fields in the context of other fields. That validation is performed after all other validations. Just add a method called context_validate that is passed the dict of all fields:
>>> class RegisterForm(Form):
... username = TextField(required=True)
... password = TextField(required=True)
... password_again = TextField(required=True)
...
... def context_validate(self, data):
... if data['password'] != data['password_again']:
... raise ValidationError(u'The two passwords must be the same')
>>> form = RegisterForm()
>>> form.validate({'username': 'admin', 'password': 'blah',
... 'password_again': 'blag'})
...
False
>>> form.errors
{None: [u'The two passwords must be the same']}
Forms can be used as fields for other forms. To create a form field of a form you can call the as_field class method:
>>> field = RegisterForm.as_field()
This field can be used like any other field class. What’s important about forms as fields is that validators don’t get an instance of RegisterForm passed as form / self but the form where it’s used in if the field is used from a form.
Form fields are bound to the form on form instanciation. This makes it possible to modify a particular instance of the form. For example you can create an instance of it and drop some fiels by using del form.fields['name'] or reassign choices of choice fields. It’s however not easily possible to add new fields to an instance because newly added fields wouldn’t be bound. The fields that are stored directly on the form can also be accessed with their name like a regular attribute.
Example usage:
>>> class StatusForm(Form):
... status = ChoiceField()
...
>>> StatusForm.status.bound
False
>>> form = StatusForm()
>>> form.status.bound
True
>>> form.status.choices = [u'happy', u'unhappy']
>>> form.validate({'status': u'happy'})
True
>>> form['status']
u'happy'
Fields support default values. These however are not as useful as you might think. These defaults are just annotations for external handling. The form validation system does not respect those values.
They are for example used in the configuration system.
Example:
>>> field = TextField(default=u'foo')