From 94c320d8a982ce30f6dd4e7556f2696229b761c7 Mon Sep 17 00:00:00 2001
From: Adrian Holovaty
Date: Thu, 20 Sep 2007 01:55:53 +0000
Subject: queryset-refactor: Merged to [6381]
git-svn-id: http://code.djangoproject.com/svn/django/branches/queryset-refactor@6382 bcc190cf-cafb-0310-a4f2-bffc1f526a37
---
tests/regressiontests/forms/tests.py | 3939 +---------------------------------
1 file changed, 46 insertions(+), 3893 deletions(-)
(limited to 'tests/regressiontests/forms/tests.py')
diff --git a/tests/regressiontests/forms/tests.py b/tests/regressiontests/forms/tests.py
index 72033a4e60..a732f9fdb0 100644
--- a/tests/regressiontests/forms/tests.py
+++ b/tests/regressiontests/forms/tests.py
@@ -1,3901 +1,54 @@
# -*- coding: utf-8 -*-
-from localflavor import localflavor_tests
-from regressions import regression_tests
-from util import util_tests
-
-form_tests = r"""
->>> from django.newforms import *
->>> from django.newforms.widgets import RadioFieldRenderer
->>> import datetime
->>> import time
->>> import re
->>> try:
-... from decimal import Decimal
-... except ImportError:
-... from django.utils._decimal import Decimal
-
-###########
-# Widgets #
-###########
-
-Each Widget class corresponds to an HTML form widget. A Widget knows how to
-render itself, given a field name and some data. Widgets don't perform
-validation.
-
-# TextInput Widget ############################################################
-
->>> w = TextInput()
->>> w.render('email', '')
-u''
->>> w.render('email', None)
-u''
->>> w.render('email', 'test@example.com')
-u''
->>> w.render('email', 'some "quoted" & ampersanded value')
-u''
->>> w.render('email', 'test@example.com', attrs={'class': 'fun'})
-u''
-
-# Note that doctest in Python 2.4 (and maybe 2.5?) doesn't support non-ascii
-# characters in output, so we're displaying the repr() here.
->>> w.render('email', 'ŠĐĆŽćžšđ', attrs={'class': 'fun'})
-u''
-
-You can also pass 'attrs' to the constructor:
->>> w = TextInput(attrs={'class': 'fun'})
->>> w.render('email', '')
-u''
->>> w.render('email', 'foo@example.com')
-u''
-
-'attrs' passed to render() get precedence over those passed to the constructor:
->>> w = TextInput(attrs={'class': 'pretty'})
->>> w.render('email', '', attrs={'class': 'special'})
-u''
-
-# PasswordInput Widget ############################################################
-
->>> w = PasswordInput()
->>> w.render('email', '')
-u''
->>> w.render('email', None)
-u''
->>> w.render('email', 'test@example.com')
-u''
->>> w.render('email', 'some "quoted" & ampersanded value')
-u''
->>> w.render('email', 'test@example.com', attrs={'class': 'fun'})
-u''
-
-You can also pass 'attrs' to the constructor:
->>> w = PasswordInput(attrs={'class': 'fun'})
->>> w.render('email', '')
-u''
->>> w.render('email', 'foo@example.com')
-u''
-
-'attrs' passed to render() get precedence over those passed to the constructor:
->>> w = PasswordInput(attrs={'class': 'pretty'})
->>> w.render('email', '', attrs={'class': 'special'})
-u''
-
->>> w.render('email', 'ŠĐĆŽćžšđ', attrs={'class': 'fun'})
-u''
-
-The render_value argument lets you specify whether the widget should render
-its value. You may want to do this for security reasons.
->>> w = PasswordInput(render_value=True)
->>> w.render('email', 'secret')
-u''
->>> w = PasswordInput(render_value=False)
->>> w.render('email', '')
-u''
->>> w.render('email', None)
-u''
->>> w.render('email', 'secret')
-u''
->>> w = PasswordInput(attrs={'class': 'fun'}, render_value=False)
->>> w.render('email', 'secret')
-u''
-
-# HiddenInput Widget ############################################################
-
->>> w = HiddenInput()
->>> w.render('email', '')
-u''
->>> w.render('email', None)
-u''
->>> w.render('email', 'test@example.com')
-u''
->>> w.render('email', 'some "quoted" & ampersanded value')
-u''
->>> w.render('email', 'test@example.com', attrs={'class': 'fun'})
-u''
-
-You can also pass 'attrs' to the constructor:
->>> w = HiddenInput(attrs={'class': 'fun'})
->>> w.render('email', '')
-u''
->>> w.render('email', 'foo@example.com')
-u''
-
-'attrs' passed to render() get precedence over those passed to the constructor:
->>> w = HiddenInput(attrs={'class': 'pretty'})
->>> w.render('email', '', attrs={'class': 'special'})
-u''
-
->>> w.render('email', 'ŠĐĆŽćžšđ', attrs={'class': 'fun'})
-u''
-
-'attrs' passed to render() get precedence over those passed to the constructor:
->>> w = HiddenInput(attrs={'class': 'pretty'})
->>> w.render('email', '', attrs={'class': 'special'})
-u''
-
-# MultipleHiddenInput Widget ##################################################
-
->>> w = MultipleHiddenInput()
->>> w.render('email', [])
-u''
->>> w.render('email', None)
-u''
->>> w.render('email', ['test@example.com'])
-u''
->>> w.render('email', ['some "quoted" & ampersanded value'])
-u''
->>> w.render('email', ['test@example.com', 'foo@example.com'])
-u'\n'
->>> w.render('email', ['test@example.com'], attrs={'class': 'fun'})
-u''
->>> w.render('email', ['test@example.com', 'foo@example.com'], attrs={'class': 'fun'})
-u'\n'
-
-You can also pass 'attrs' to the constructor:
->>> w = MultipleHiddenInput(attrs={'class': 'fun'})
->>> w.render('email', [])
-u''
->>> w.render('email', ['foo@example.com'])
-u''
->>> w.render('email', ['foo@example.com', 'test@example.com'])
-u'\n'
-
-'attrs' passed to render() get precedence over those passed to the constructor:
->>> w = MultipleHiddenInput(attrs={'class': 'pretty'})
->>> w.render('email', ['foo@example.com'], attrs={'class': 'special'})
-u''
-
->>> w.render('email', ['ŠĐĆŽćžšđ'], attrs={'class': 'fun'})
-u''
-
-'attrs' passed to render() get precedence over those passed to the constructor:
->>> w = MultipleHiddenInput(attrs={'class': 'pretty'})
->>> w.render('email', ['foo@example.com'], attrs={'class': 'special'})
-u''
-
-# FileInput Widget ############################################################
-
-FileInput widgets don't ever show the value, because the old value is of no use
-if you are updating the form or if the provided file generated an error.
->>> w = FileInput()
->>> w.render('email', '')
-u''
->>> w.render('email', None)
-u''
->>> w.render('email', 'test@example.com')
-u''
->>> w.render('email', 'some "quoted" & ampersanded value')
-u''
->>> w.render('email', 'test@example.com', attrs={'class': 'fun'})
-u''
-
-You can also pass 'attrs' to the constructor:
->>> w = FileInput(attrs={'class': 'fun'})
->>> w.render('email', '')
-u''
->>> w.render('email', 'foo@example.com')
-u''
-
->>> w.render('email', 'ŠĐĆŽćžšđ', attrs={'class': 'fun'})
-u''
-
-# Textarea Widget #############################################################
-
->>> w = Textarea()
->>> w.render('msg', '')
-u''
->>> w.render('msg', None)
-u''
->>> w.render('msg', 'value')
-u''
->>> w.render('msg', 'some "quoted" & ampersanded value')
-u''
->>> w.render('msg', 'value', attrs={'class': 'pretty', 'rows': 20})
-u''
-
-You can also pass 'attrs' to the constructor:
->>> w = Textarea(attrs={'class': 'pretty'})
->>> w.render('msg', '')
-u''
->>> w.render('msg', 'example')
-u''
-
-'attrs' passed to render() get precedence over those passed to the constructor:
->>> w = Textarea(attrs={'class': 'pretty'})
->>> w.render('msg', '', attrs={'class': 'special'})
-u''
-
->>> w.render('msg', 'ŠĐĆŽćžšđ', attrs={'class': 'fun'})
-u''
-
-# CheckboxInput Widget ########################################################
-
->>> w = CheckboxInput()
->>> w.render('is_cool', '')
-u''
->>> w.render('is_cool', None)
-u''
->>> w.render('is_cool', False)
-u''
->>> w.render('is_cool', True)
-u''
-
-Using any value that's not in ('', None, False, True) will check the checkbox
-and set the 'value' attribute.
->>> w.render('is_cool', 'foo')
-u''
-
->>> w.render('is_cool', False, attrs={'class': 'pretty'})
-u''
-
-You can also pass 'attrs' to the constructor:
->>> w = CheckboxInput(attrs={'class': 'pretty'})
->>> w.render('is_cool', '')
-u''
-
-'attrs' passed to render() get precedence over those passed to the constructor:
->>> w = CheckboxInput(attrs={'class': 'pretty'})
->>> w.render('is_cool', '', attrs={'class': 'special'})
-u''
-
-You can pass 'check_test' to the constructor. This is a callable that takes the
-value and returns True if the box should be checked.
->>> w = CheckboxInput(check_test=lambda value: value.startswith('hello'))
->>> w.render('greeting', '')
-u''
->>> w.render('greeting', 'hello')
-u''
->>> w.render('greeting', 'hello there')
-u''
->>> w.render('greeting', 'hello & goodbye')
-u''
-
-A subtlety: If the 'check_test' argument cannot handle a value and raises any
-exception during its __call__, then the exception will be swallowed and the box
-will not be checked. In this example, the 'check_test' assumes the value has a
-startswith() method, which fails for the values True, False and None.
->>> w.render('greeting', True)
-u''
->>> w.render('greeting', False)
-u''
->>> w.render('greeting', None)
-u''
-
-# Select Widget ###############################################################
-
->>> w = Select()
->>> print w.render('beatle', 'J', choices=(('J', 'John'), ('P', 'Paul'), ('G', 'George'), ('R', 'Ringo')))
-
-
-If the value is None, none of the options are selected:
->>> print w.render('beatle', None, choices=(('J', 'John'), ('P', 'Paul'), ('G', 'George'), ('R', 'Ringo')))
-
-
-If the value corresponds to a label (but not to an option value), none of the options are selected:
->>> print w.render('beatle', 'John', choices=(('J', 'John'), ('P', 'Paul'), ('G', 'George'), ('R', 'Ringo')))
-
-
-The value is compared to its str():
->>> print w.render('num', 2, choices=[('1', '1'), ('2', '2'), ('3', '3')])
-
->>> print w.render('num', '2', choices=[(1, 1), (2, 2), (3, 3)])
-
->>> print w.render('num', 2, choices=[(1, 1), (2, 2), (3, 3)])
-
-
-The 'choices' argument can be any iterable:
->>> from itertools import chain
->>> def get_choices():
-... for i in range(5):
-... yield (i, i)
->>> print w.render('num', 2, choices=get_choices())
-
->>> things = ({'id': 1, 'name': 'And Boom'}, {'id': 2, 'name': 'One More Thing!'})
->>> class SomeForm(Form):
-... somechoice = ChoiceField(choices=chain((('', '-'*9),), [(thing['id'], thing['name']) for thing in things]))
->>> f = SomeForm()
->>> f.as_table()
-u'
'
->>> f.as_table()
-u'
'
->>> f = SomeForm({'somechoice': 2})
->>> f.as_table()
-u'
'
-
-You can also pass 'choices' to the constructor:
->>> w = Select(choices=[(1, 1), (2, 2), (3, 3)])
->>> print w.render('num', 2)
-
-
-If 'choices' is passed to both the constructor and render(), then they'll both be in the output:
->>> print w.render('num', 2, choices=[(4, 4), (5, 5)])
-
-
->>> w.render('email', 'ŠĐĆŽćžšđ', choices=[('ŠĐĆŽćžšđ', 'ŠĐabcĆŽćžšđ'), ('ćžšđ', 'abcćžšđ')])
-u''
-
-If choices is passed to the constructor and is a generator, it can be iterated
-over multiple times without getting consumed:
->>> w = Select(choices=get_choices())
->>> print w.render('num', 2)
-
->>> print w.render('num', 3)
-
-
-# NullBooleanSelect Widget ####################################################
-
->>> w = NullBooleanSelect()
->>> print w.render('is_cool', True)
-
->>> print w.render('is_cool', False)
-
->>> print w.render('is_cool', None)
-
->>> print w.render('is_cool', '2')
-
->>> print w.render('is_cool', '3')
-
-
-# SelectMultiple Widget #######################################################
-
->>> w = SelectMultiple()
->>> print w.render('beatles', ['J'], choices=(('J', 'John'), ('P', 'Paul'), ('G', 'George'), ('R', 'Ringo')))
-
->>> print w.render('beatles', ['J', 'P'], choices=(('J', 'John'), ('P', 'Paul'), ('G', 'George'), ('R', 'Ringo')))
-
->>> print w.render('beatles', ['J', 'P', 'R'], choices=(('J', 'John'), ('P', 'Paul'), ('G', 'George'), ('R', 'Ringo')))
-
-
-If the value is None, none of the options are selected:
->>> print w.render('beatles', None, choices=(('J', 'John'), ('P', 'Paul'), ('G', 'George'), ('R', 'Ringo')))
-
-
-If the value corresponds to a label (but not to an option value), none of the options are selected:
->>> print w.render('beatles', ['John'], choices=(('J', 'John'), ('P', 'Paul'), ('G', 'George'), ('R', 'Ringo')))
-
-
-If multiple values are given, but some of them are not valid, the valid ones are selected:
->>> print w.render('beatles', ['J', 'G', 'foo'], choices=(('J', 'John'), ('P', 'Paul'), ('G', 'George'), ('R', 'Ringo')))
-
-
-The value is compared to its str():
->>> print w.render('nums', [2], choices=[('1', '1'), ('2', '2'), ('3', '3')])
-
->>> print w.render('nums', ['2'], choices=[(1, 1), (2, 2), (3, 3)])
-
->>> print w.render('nums', [2], choices=[(1, 1), (2, 2), (3, 3)])
-
-
-The 'choices' argument can be any iterable:
->>> def get_choices():
-... for i in range(5):
-... yield (i, i)
->>> print w.render('nums', [2], choices=get_choices())
-
-
-You can also pass 'choices' to the constructor:
->>> w = SelectMultiple(choices=[(1, 1), (2, 2), (3, 3)])
->>> print w.render('nums', [2])
-
-
-If 'choices' is passed to both the constructor and render(), then they'll both be in the output:
->>> print w.render('nums', [2], choices=[(4, 4), (5, 5)])
-
-
->>> w.render('nums', ['ŠĐĆŽćžšđ'], choices=[('ŠĐĆŽćžšđ', 'ŠĐabcĆŽćžšđ'), ('ćžšđ', 'abcćžšđ')])
-u''
-
-# RadioSelect Widget ##########################################################
-
->>> w = RadioSelect()
->>> print w.render('beatle', 'J', choices=(('J', 'John'), ('P', 'Paul'), ('G', 'George'), ('R', 'Ringo')))
-
-
-
-
-
-
-
-If the value is None, none of the options are checked:
->>> print w.render('beatle', None, choices=(('J', 'John'), ('P', 'Paul'), ('G', 'George'), ('R', 'Ringo')))
-
-
-
-
-
-
-
-If the value corresponds to a label (but not to an option value), none of the options are checked:
->>> print w.render('beatle', 'John', choices=(('J', 'John'), ('P', 'Paul'), ('G', 'George'), ('R', 'Ringo')))
-
-
-
-
-
-
-
-The value is compared to its str():
->>> print w.render('num', 2, choices=[('1', '1'), ('2', '2'), ('3', '3')])
-
-
-The 'choices' argument can be any iterable:
->>> def get_choices():
-... for i in range(5):
-... yield (i, i)
->>> print w.render('num', 2, choices=get_choices())
-
-
-
-
-
-
-
-
-You can also pass 'choices' to the constructor:
->>> w = RadioSelect(choices=[(1, 1), (2, 2), (3, 3)])
->>> print w.render('num', 2)
-
-
-
-
-
-
-If 'choices' is passed to both the constructor and render(), then they'll both be in the output:
->>> print w.render('num', 2, choices=[(4, 4), (5, 5)])
-
-
-
-
-
-
-
-
-RadioSelect uses a RadioFieldRenderer to render the individual radio inputs.
-You can manipulate that object directly to customize the way the RadioSelect
-is rendered.
->>> w = RadioSelect()
->>> r = w.get_renderer('beatle', 'J', choices=(('J', 'John'), ('P', 'Paul'), ('G', 'George'), ('R', 'Ringo')))
->>> for inp in r:
-... print inp
-
-
-
-
->>> for inp in r:
-... print '%s ' % inp
-
-
-
-
->>> for inp in r:
-... print '
%s %s
' % (inp.tag(), inp.choice_label)
-
John
-
Paul
-
George
-
Ringo
->>> for inp in r:
-... print '%s %s %s %s %s' % (inp.name, inp.value, inp.choice_value, inp.choice_label, inp.is_checked())
-beatle J J John True
-beatle J P Paul False
-beatle J G George False
-beatle J R Ringo False
-
-You can create your own custom renderers for RadioSelect to use.
->>> class MyRenderer(RadioFieldRenderer):
-... def render(self):
-... return u' \n'.join([unicode(choice) for choice in self])
->>> w = RadioSelect(renderer=MyRenderer)
->>> print w.render('beatle', 'G', choices=(('J', 'John'), ('P', 'Paul'), ('G', 'George'), ('R', 'Ringo')))
-
-
-
-
-
-A RadioFieldRenderer object also allows index access to individual RadioInput
-objects.
->>> w = RadioSelect()
->>> r = w.get_renderer('beatle', 'J', choices=(('J', 'John'), ('P', 'Paul'), ('G', 'George'), ('R', 'Ringo')))
->>> print r[1]
-
->>> print r[0]
-
->>> r[0].is_checked()
-True
->>> r[1].is_checked()
-False
->>> r[1].name, r[1].value, r[1].choice_value, r[1].choice_label
-('beatle', u'J', u'P', u'Paul')
->>> r[10]
-Traceback (most recent call last):
-...
-IndexError: list index out of range
-
-# Unicode choices are correctly rendered as HTML
->>> w = RadioSelect()
->>> unicode(w.render('email', 'ŠĐĆŽćžšđ', choices=[('ŠĐĆŽćžšđ', 'ŠĐabcĆŽćžšđ'), ('ćžšđ', 'abcćžšđ')]))
-u'
\n\n\n
'
-
-# Attributes provided at instantiation are passed to the constituent inputs
->>> w = RadioSelect(attrs={'id':'foo'})
->>> print w.render('beatle', 'J', choices=(('J', 'John'), ('P', 'Paul'), ('G', 'George'), ('R', 'Ringo')))
-
-
-
-
-
-
-
-# Attributes provided at render-time are passed to the constituent inputs
->>> w = RadioSelect()
->>> print w.render('beatle', 'J', choices=(('J', 'John'), ('P', 'Paul'), ('G', 'George'), ('R', 'Ringo')), attrs={'id':'bar'})
-
-
-If the value is None, none of the options are selected:
->>> print w.render('beatles', None, choices=(('J', 'John'), ('P', 'Paul'), ('G', 'George'), ('R', 'Ringo')))
-
-
-
-
-
-
-
-If the value corresponds to a label (but not to an option value), none of the options are selected:
->>> print w.render('beatles', ['John'], choices=(('J', 'John'), ('P', 'Paul'), ('G', 'George'), ('R', 'Ringo')))
-
-
-
-
-
-
-
-If multiple values are given, but some of them are not valid, the valid ones are selected:
->>> print w.render('beatles', ['J', 'G', 'foo'], choices=(('J', 'John'), ('P', 'Paul'), ('G', 'George'), ('R', 'Ringo')))
-
-
-
-
-
-
-
-The value is compared to its str():
->>> print w.render('nums', [2], choices=[('1', '1'), ('2', '2'), ('3', '3')])
-
-
-The 'choices' argument can be any iterable:
->>> def get_choices():
-... for i in range(5):
-... yield (i, i)
->>> print w.render('nums', [2], choices=get_choices())
-
-
-
-
-
-
-
-
-You can also pass 'choices' to the constructor:
->>> w = CheckboxSelectMultiple(choices=[(1, 1), (2, 2), (3, 3)])
->>> print w.render('nums', [2])
-
-
-
-
-
-
-If 'choices' is passed to both the constructor and render(), then they'll both be in the output:
->>> print w.render('nums', [2], choices=[(4, 4), (5, 5)])
-
'
-
-# MultiWidget #################################################################
-
->>> class MyMultiWidget(MultiWidget):
-... def decompress(self, value):
-... if value:
-... return value.split('__')
-... return ['', '']
-... def format_output(self, rendered_widgets):
-... return u' '.join(rendered_widgets)
->>> w = MyMultiWidget(widgets=(TextInput(attrs={'class': 'big'}), TextInput(attrs={'class': 'small'})))
->>> w.render('name', ['john', 'lennon'])
-u' '
->>> w.render('name', 'john__lennon')
-u' '
->>> w.render('name', 'john__lennon', attrs={'id':'foo'})
-u' '
->>> w = MyMultiWidget(widgets=(TextInput(attrs={'class': 'big'}), TextInput(attrs={'class': 'small'})), attrs={'id': 'bar'})
->>> w.render('name', ['john', 'lennon'])
-u' '
-
-# SplitDateTimeWidget #########################################################
-
->>> w = SplitDateTimeWidget()
->>> w.render('date', '')
-u''
->>> w.render('date', None)
-u''
->>> w.render('date', datetime.datetime(2006, 1, 10, 7, 30))
-u''
->>> w.render('date', [datetime.date(2006, 1, 10), datetime.time(7, 30)])
-u''
-
-You can also pass 'attrs' to the constructor. In this case, the attrs will be
-included on both widgets.
->>> w = SplitDateTimeWidget(attrs={'class': 'pretty'})
->>> w.render('date', datetime.datetime(2006, 1, 10, 7, 30))
-u''
-
-##########
-# Fields #
-##########
-
-Each Field class does some sort of validation. Each Field has a clean() method,
-which either raises django.newforms.ValidationError or returns the "clean"
-data -- usually a Unicode object, but, in some rare cases, a list.
-
-Each Field's __init__() takes at least these parameters:
- required -- Boolean that specifies whether the field is required.
- True by default.
- widget -- A Widget class, or instance of a Widget class, that should be
- used for this Field when displaying it. Each Field has a default
- Widget that it'll use if you don't specify this. In most cases,
- the default widget is TextInput.
- label -- A verbose name for this field, for use in displaying this field in
- a form. By default, Django will use a "pretty" version of the form
- field name, if the Field is part of a Form.
- initial -- A value to use in this Field's initial display. This value is
- *not* used as a fallback if data isn't given.
-
-Other than that, the Field subclasses have class-specific options for
-__init__(). For example, CharField has a max_length option.
-
-# CharField ###################################################################
-
->>> f = CharField()
->>> f.clean(1)
-u'1'
->>> f.clean('hello')
-u'hello'
->>> f.clean(None)
-Traceback (most recent call last):
-...
-ValidationError: [u'This field is required.']
->>> f.clean('')
-Traceback (most recent call last):
-...
-ValidationError: [u'This field is required.']
->>> f.clean([1, 2, 3])
-u'[1, 2, 3]'
-
->>> f = CharField(required=False)
->>> f.clean(1)
-u'1'
->>> f.clean('hello')
-u'hello'
->>> f.clean(None)
-u''
->>> f.clean('')
-u''
->>> f.clean([1, 2, 3])
-u'[1, 2, 3]'
-
-CharField accepts an optional max_length parameter:
->>> f = CharField(max_length=10, required=False)
->>> f.clean('12345')
-u'12345'
->>> f.clean('1234567890')
-u'1234567890'
->>> f.clean('1234567890a')
-Traceback (most recent call last):
-...
-ValidationError: [u'Ensure this value has at most 10 characters (it has 11).']
-
-CharField accepts an optional min_length parameter:
->>> f = CharField(min_length=10, required=False)
->>> f.clean('')
-u''
->>> f.clean('12345')
-Traceback (most recent call last):
-...
-ValidationError: [u'Ensure this value has at least 10 characters (it has 5).']
->>> f.clean('1234567890')
-u'1234567890'
->>> f.clean('1234567890a')
-u'1234567890a'
-
->>> f = CharField(min_length=10, required=True)
->>> f.clean('')
-Traceback (most recent call last):
-...
-ValidationError: [u'This field is required.']
->>> f.clean('12345')
-Traceback (most recent call last):
-...
-ValidationError: [u'Ensure this value has at least 10 characters (it has 5).']
->>> f.clean('1234567890')
-u'1234567890'
->>> f.clean('1234567890a')
-u'1234567890a'
-
-# IntegerField ################################################################
-
->>> f = IntegerField()
->>> f.clean('')
-Traceback (most recent call last):
-...
-ValidationError: [u'This field is required.']
->>> f.clean(None)
-Traceback (most recent call last):
-...
-ValidationError: [u'This field is required.']
->>> f.clean('1')
-1
->>> isinstance(f.clean('1'), int)
-True
->>> f.clean('23')
-23
->>> f.clean('a')
-Traceback (most recent call last):
-...
-ValidationError: [u'Enter a whole number.']
->>> f.clean(42)
-42
->>> f.clean(3.14)
-Traceback (most recent call last):
-...
-ValidationError: [u'Enter a whole number.']
->>> f.clean('1 ')
-1
->>> f.clean(' 1')
-1
->>> f.clean(' 1 ')
-1
->>> f.clean('1a')
-Traceback (most recent call last):
-...
-ValidationError: [u'Enter a whole number.']
-
->>> f = IntegerField(required=False)
->>> f.clean('')
->>> repr(f.clean(''))
-'None'
->>> f.clean(None)
->>> repr(f.clean(None))
-'None'
->>> f.clean('1')
-1
->>> isinstance(f.clean('1'), int)
-True
->>> f.clean('23')
-23
->>> f.clean('a')
-Traceback (most recent call last):
-...
-ValidationError: [u'Enter a whole number.']
->>> f.clean('1 ')
-1
->>> f.clean(' 1')
-1
->>> f.clean(' 1 ')
-1
->>> f.clean('1a')
-Traceback (most recent call last):
-...
-ValidationError: [u'Enter a whole number.']
-
-IntegerField accepts an optional max_value parameter:
->>> f = IntegerField(max_value=10)
->>> f.clean(None)
-Traceback (most recent call last):
-...
-ValidationError: [u'This field is required.']
->>> f.clean(1)
-1
->>> f.clean(10)
-10
->>> f.clean(11)
-Traceback (most recent call last):
-...
-ValidationError: [u'Ensure this value is less than or equal to 10.']
->>> f.clean('10')
-10
->>> f.clean('11')
-Traceback (most recent call last):
-...
-ValidationError: [u'Ensure this value is less than or equal to 10.']
-
-IntegerField accepts an optional min_value parameter:
->>> f = IntegerField(min_value=10)
->>> f.clean(None)
-Traceback (most recent call last):
-...
-ValidationError: [u'This field is required.']
->>> f.clean(1)
-Traceback (most recent call last):
-...
-ValidationError: [u'Ensure this value is greater than or equal to 10.']
->>> f.clean(10)
-10
->>> f.clean(11)
-11
->>> f.clean('10')
-10
->>> f.clean('11')
-11
-
-min_value and max_value can be used together:
->>> f = IntegerField(min_value=10, max_value=20)
->>> f.clean(None)
-Traceback (most recent call last):
-...
-ValidationError: [u'This field is required.']
->>> f.clean(1)
-Traceback (most recent call last):
-...
-ValidationError: [u'Ensure this value is greater than or equal to 10.']
->>> f.clean(10)
-10
->>> f.clean(11)
-11
->>> f.clean('10')
-10
->>> f.clean('11')
-11
->>> f.clean(20)
-20
->>> f.clean(21)
-Traceback (most recent call last):
-...
-ValidationError: [u'Ensure this value is less than or equal to 20.']
-
-# FloatField ##################################################################
-
->>> f = FloatField()
->>> f.clean('')
-Traceback (most recent call last):
-...
-ValidationError: [u'This field is required.']
->>> f.clean(None)
-Traceback (most recent call last):
-...
-ValidationError: [u'This field is required.']
->>> f.clean('1')
-1.0
->>> isinstance(f.clean('1'), float)
-True
->>> f.clean('23')
-23.0
->>> f.clean('3.14')
-3.1400000000000001
->>> f.clean(3.14)
-3.1400000000000001
->>> f.clean(42)
-42.0
->>> f.clean('a')
-Traceback (most recent call last):
-...
-ValidationError: [u'Enter a number.']
->>> f.clean('1.0 ')
-1.0
->>> f.clean(' 1.0')
-1.0
->>> f.clean(' 1.0 ')
-1.0
->>> f.clean('1.0a')
-Traceback (most recent call last):
-...
-ValidationError: [u'Enter a number.']
-
->>> f = FloatField(required=False)
->>> f.clean('')
-
->>> f.clean(None)
-
->>> f.clean('1')
-1.0
-
-FloatField accepts min_value and max_value just like IntegerField:
->>> f = FloatField(max_value=1.5, min_value=0.5)
-
->>> f.clean('1.6')
-Traceback (most recent call last):
-...
-ValidationError: [u'Ensure this value is less than or equal to 1.5.']
->>> f.clean('0.4')
-Traceback (most recent call last):
-...
-ValidationError: [u'Ensure this value is greater than or equal to 0.5.']
->>> f.clean('1.5')
-1.5
->>> f.clean('0.5')
-0.5
-
-# DecimalField ################################################################
-
->>> f = DecimalField(max_digits=4, decimal_places=2)
->>> f.clean('')
-Traceback (most recent call last):
-...
-ValidationError: [u'This field is required.']
->>> f.clean(None)
-Traceback (most recent call last):
-...
-ValidationError: [u'This field is required.']
->>> f.clean('1')
-Decimal("1")
->>> isinstance(f.clean('1'), Decimal)
-True
->>> f.clean('23')
-Decimal("23")
->>> f.clean('3.14')
-Decimal("3.14")
->>> f.clean(3.14)
-Decimal("3.14")
->>> f.clean(Decimal('3.14'))
-Decimal("3.14")
->>> f.clean('a')
-Traceback (most recent call last):
-...
-ValidationError: [u'Enter a number.']
->>> f.clean('1.0 ')
-Decimal("1.0")
->>> f.clean(' 1.0')
-Decimal("1.0")
->>> f.clean(' 1.0 ')
-Decimal("1.0")
->>> f.clean('1.0a')
-Traceback (most recent call last):
-...
-ValidationError: [u'Enter a number.']
->>> f.clean('123.45')
-Traceback (most recent call last):
-...
-ValidationError: [u'Ensure that there are no more than 4 digits in total.']
->>> f.clean('1.234')
-Traceback (most recent call last):
-...
-ValidationError: [u'Ensure that there are no more than 2 decimal places.']
->>> f.clean('123.4')
-Traceback (most recent call last):
-...
-ValidationError: [u'Ensure that there are no more than 2 digits before the decimal point.']
->>> f.clean('-12.34')
-Decimal("-12.34")
->>> f.clean('-123.45')
-Traceback (most recent call last):
-...
-ValidationError: [u'Ensure that there are no more than 4 digits in total.']
->>> f.clean('-.12')
-Decimal("-0.12")
->>> f.clean('-00.12')
-Decimal("-0.12")
->>> f.clean('-000.12')
-Decimal("-0.12")
->>> f.clean('-000.123')
-Traceback (most recent call last):
-...
-ValidationError: [u'Ensure that there are no more than 2 decimal places.']
->>> f.clean('-000.1234')
-Traceback (most recent call last):
-...
-ValidationError: [u'Ensure that there are no more than 4 digits in total.']
->>> f.clean('--0.12')
-Traceback (most recent call last):
-...
-ValidationError: [u'Enter a number.']
-
->>> f = DecimalField(max_digits=4, decimal_places=2, required=False)
->>> f.clean('')
-
->>> f.clean(None)
-
->>> f.clean('1')
-Decimal("1")
-
-DecimalField accepts min_value and max_value just like IntegerField:
->>> f = DecimalField(max_digits=4, decimal_places=2, max_value=Decimal('1.5'), min_value=Decimal('0.5'))
-
->>> f.clean('1.6')
-Traceback (most recent call last):
-...
-ValidationError: [u'Ensure this value is less than or equal to 1.5.']
->>> f.clean('0.4')
-Traceback (most recent call last):
-...
-ValidationError: [u'Ensure this value is greater than or equal to 0.5.']
->>> f.clean('1.5')
-Decimal("1.5")
->>> f.clean('0.5')
-Decimal("0.5")
->>> f.clean('.5')
-Decimal("0.5")
->>> f.clean('00.50')
-Decimal("0.50")
-
-# DateField ###################################################################
-
->>> import datetime
->>> f = DateField()
->>> f.clean(datetime.date(2006, 10, 25))
-datetime.date(2006, 10, 25)
->>> f.clean(datetime.datetime(2006, 10, 25, 14, 30))
-datetime.date(2006, 10, 25)
->>> f.clean(datetime.datetime(2006, 10, 25, 14, 30, 59))
-datetime.date(2006, 10, 25)
->>> f.clean(datetime.datetime(2006, 10, 25, 14, 30, 59, 200))
-datetime.date(2006, 10, 25)
->>> f.clean('2006-10-25')
-datetime.date(2006, 10, 25)
->>> f.clean('10/25/2006')
-datetime.date(2006, 10, 25)
->>> f.clean('10/25/06')
-datetime.date(2006, 10, 25)
->>> f.clean('Oct 25 2006')
-datetime.date(2006, 10, 25)
->>> f.clean('October 25 2006')
-datetime.date(2006, 10, 25)
->>> f.clean('October 25, 2006')
-datetime.date(2006, 10, 25)
->>> f.clean('25 October 2006')
-datetime.date(2006, 10, 25)
->>> f.clean('25 October, 2006')
-datetime.date(2006, 10, 25)
->>> f.clean('2006-4-31')
-Traceback (most recent call last):
-...
-ValidationError: [u'Enter a valid date.']
->>> f.clean('200a-10-25')
-Traceback (most recent call last):
-...
-ValidationError: [u'Enter a valid date.']
->>> f.clean('25/10/06')
-Traceback (most recent call last):
-...
-ValidationError: [u'Enter a valid date.']
->>> f.clean(None)
-Traceback (most recent call last):
-...
-ValidationError: [u'This field is required.']
-
->>> f = DateField(required=False)
->>> f.clean(None)
->>> repr(f.clean(None))
-'None'
->>> f.clean('')
->>> repr(f.clean(''))
-'None'
-
-DateField accepts an optional input_formats parameter:
->>> f = DateField(input_formats=['%Y %m %d'])
->>> f.clean(datetime.date(2006, 10, 25))
-datetime.date(2006, 10, 25)
->>> f.clean(datetime.datetime(2006, 10, 25, 14, 30))
-datetime.date(2006, 10, 25)
->>> f.clean('2006 10 25')
-datetime.date(2006, 10, 25)
-
-The input_formats parameter overrides all default input formats,
-so the default formats won't work unless you specify them:
->>> f.clean('2006-10-25')
-Traceback (most recent call last):
-...
-ValidationError: [u'Enter a valid date.']
->>> f.clean('10/25/2006')
-Traceback (most recent call last):
-...
-ValidationError: [u'Enter a valid date.']
->>> f.clean('10/25/06')
-Traceback (most recent call last):
-...
-ValidationError: [u'Enter a valid date.']
-
-# TimeField ###################################################################
-
->>> import datetime
->>> f = TimeField()
->>> f.clean(datetime.time(14, 25))
-datetime.time(14, 25)
->>> f.clean(datetime.time(14, 25, 59))
-datetime.time(14, 25, 59)
->>> f.clean('14:25')
-datetime.time(14, 25)
->>> f.clean('14:25:59')
-datetime.time(14, 25, 59)
->>> f.clean('hello')
-Traceback (most recent call last):
-...
-ValidationError: [u'Enter a valid time.']
->>> f.clean('1:24 p.m.')
-Traceback (most recent call last):
-...
-ValidationError: [u'Enter a valid time.']
-
-TimeField accepts an optional input_formats parameter:
->>> f = TimeField(input_formats=['%I:%M %p'])
->>> f.clean(datetime.time(14, 25))
-datetime.time(14, 25)
->>> f.clean(datetime.time(14, 25, 59))
-datetime.time(14, 25, 59)
->>> f.clean('4:25 AM')
-datetime.time(4, 25)
->>> f.clean('4:25 PM')
-datetime.time(16, 25)
-
-The input_formats parameter overrides all default input formats,
-so the default formats won't work unless you specify them:
->>> f.clean('14:30:45')
-Traceback (most recent call last):
-...
-ValidationError: [u'Enter a valid time.']
-
-# DateTimeField ###############################################################
-
->>> import datetime
->>> f = DateTimeField()
->>> f.clean(datetime.date(2006, 10, 25))
-datetime.datetime(2006, 10, 25, 0, 0)
->>> f.clean(datetime.datetime(2006, 10, 25, 14, 30))
-datetime.datetime(2006, 10, 25, 14, 30)
->>> f.clean(datetime.datetime(2006, 10, 25, 14, 30, 59))
-datetime.datetime(2006, 10, 25, 14, 30, 59)
->>> f.clean(datetime.datetime(2006, 10, 25, 14, 30, 59, 200))
-datetime.datetime(2006, 10, 25, 14, 30, 59, 200)
->>> f.clean('2006-10-25 14:30:45')
-datetime.datetime(2006, 10, 25, 14, 30, 45)
->>> f.clean('2006-10-25 14:30:00')
-datetime.datetime(2006, 10, 25, 14, 30)
->>> f.clean('2006-10-25 14:30')
-datetime.datetime(2006, 10, 25, 14, 30)
->>> f.clean('2006-10-25')
-datetime.datetime(2006, 10, 25, 0, 0)
->>> f.clean('10/25/2006 14:30:45')
-datetime.datetime(2006, 10, 25, 14, 30, 45)
->>> f.clean('10/25/2006 14:30:00')
-datetime.datetime(2006, 10, 25, 14, 30)
->>> f.clean('10/25/2006 14:30')
-datetime.datetime(2006, 10, 25, 14, 30)
->>> f.clean('10/25/2006')
-datetime.datetime(2006, 10, 25, 0, 0)
->>> f.clean('10/25/06 14:30:45')
-datetime.datetime(2006, 10, 25, 14, 30, 45)
->>> f.clean('10/25/06 14:30:00')
-datetime.datetime(2006, 10, 25, 14, 30)
->>> f.clean('10/25/06 14:30')
-datetime.datetime(2006, 10, 25, 14, 30)
->>> f.clean('10/25/06')
-datetime.datetime(2006, 10, 25, 0, 0)
->>> f.clean('hello')
-Traceback (most recent call last):
-...
-ValidationError: [u'Enter a valid date/time.']
->>> f.clean('2006-10-25 4:30 p.m.')
-Traceback (most recent call last):
-...
-ValidationError: [u'Enter a valid date/time.']
-
-DateField accepts an optional input_formats parameter:
->>> f = DateTimeField(input_formats=['%Y %m %d %I:%M %p'])
->>> f.clean(datetime.date(2006, 10, 25))
-datetime.datetime(2006, 10, 25, 0, 0)
->>> f.clean(datetime.datetime(2006, 10, 25, 14, 30))
-datetime.datetime(2006, 10, 25, 14, 30)
->>> f.clean(datetime.datetime(2006, 10, 25, 14, 30, 59))
-datetime.datetime(2006, 10, 25, 14, 30, 59)
->>> f.clean(datetime.datetime(2006, 10, 25, 14, 30, 59, 200))
-datetime.datetime(2006, 10, 25, 14, 30, 59, 200)
->>> f.clean('2006 10 25 2:30 PM')
-datetime.datetime(2006, 10, 25, 14, 30)
-
-The input_formats parameter overrides all default input formats,
-so the default formats won't work unless you specify them:
->>> f.clean('2006-10-25 14:30:45')
-Traceback (most recent call last):
-...
-ValidationError: [u'Enter a valid date/time.']
-
->>> f = DateTimeField(required=False)
->>> f.clean(None)
->>> repr(f.clean(None))
-'None'
->>> f.clean('')
->>> repr(f.clean(''))
-'None'
-
-# RegexField ##################################################################
-
->>> f = RegexField('^\d[A-F]\d$')
->>> f.clean('2A2')
-u'2A2'
->>> f.clean('3F3')
-u'3F3'
->>> f.clean('3G3')
-Traceback (most recent call last):
-...
-ValidationError: [u'Enter a valid value.']
->>> f.clean(' 2A2')
-Traceback (most recent call last):
-...
-ValidationError: [u'Enter a valid value.']
->>> f.clean('2A2 ')
-Traceback (most recent call last):
-...
-ValidationError: [u'Enter a valid value.']
->>> f.clean('')
-Traceback (most recent call last):
-...
-ValidationError: [u'This field is required.']
-
->>> f = RegexField('^\d[A-F]\d$', required=False)
->>> f.clean('2A2')
-u'2A2'
->>> f.clean('3F3')
-u'3F3'
->>> f.clean('3G3')
-Traceback (most recent call last):
-...
-ValidationError: [u'Enter a valid value.']
->>> f.clean('')
-u''
-
-Alternatively, RegexField can take a compiled regular expression:
->>> f = RegexField(re.compile('^\d[A-F]\d$'))
->>> f.clean('2A2')
-u'2A2'
->>> f.clean('3F3')
-u'3F3'
->>> f.clean('3G3')
-Traceback (most recent call last):
-...
-ValidationError: [u'Enter a valid value.']
->>> f.clean(' 2A2')
-Traceback (most recent call last):
-...
-ValidationError: [u'Enter a valid value.']
->>> f.clean('2A2 ')
-Traceback (most recent call last):
-...
-ValidationError: [u'Enter a valid value.']
-
-RegexField takes an optional error_message argument:
->>> f = RegexField('^\d\d\d\d$', error_message='Enter a four-digit number.')
->>> f.clean('1234')
-u'1234'
->>> f.clean('123')
-Traceback (most recent call last):
-...
-ValidationError: [u'Enter a four-digit number.']
->>> f.clean('abcd')
-Traceback (most recent call last):
-...
-ValidationError: [u'Enter a four-digit number.']
-
-RegexField also access min_length and max_length parameters, for convenience.
->>> f = RegexField('^\d+$', min_length=5, max_length=10)
->>> f.clean('123')
-Traceback (most recent call last):
-...
-ValidationError: [u'Ensure this value has at least 5 characters (it has 3).']
->>> f.clean('abc')
-Traceback (most recent call last):
-...
-ValidationError: [u'Ensure this value has at least 5 characters (it has 3).']
->>> f.clean('12345')
-u'12345'
->>> f.clean('1234567890')
-u'1234567890'
->>> f.clean('12345678901')
-Traceback (most recent call last):
-...
-ValidationError: [u'Ensure this value has at most 10 characters (it has 11).']
->>> f.clean('12345a')
-Traceback (most recent call last):
-...
-ValidationError: [u'Enter a valid value.']
-
-# EmailField ##################################################################
-
->>> f = EmailField()
->>> f.clean('')
-Traceback (most recent call last):
-...
-ValidationError: [u'This field is required.']
->>> f.clean(None)
-Traceback (most recent call last):
-...
-ValidationError: [u'This field is required.']
->>> f.clean('person@example.com')
-u'person@example.com'
->>> f.clean('foo')
-Traceback (most recent call last):
-...
-ValidationError: [u'Enter a valid e-mail address.']
->>> f.clean('foo@')
-Traceback (most recent call last):
-...
-ValidationError: [u'Enter a valid e-mail address.']
->>> f.clean('foo@bar')
-Traceback (most recent call last):
-...
-ValidationError: [u'Enter a valid e-mail address.']
-
->>> f = EmailField(required=False)
->>> f.clean('')
-u''
->>> f.clean(None)
-u''
->>> f.clean('person@example.com')
-u'person@example.com'
->>> f.clean('foo')
-Traceback (most recent call last):
-...
-ValidationError: [u'Enter a valid e-mail address.']
->>> f.clean('foo@')
-Traceback (most recent call last):
-...
-ValidationError: [u'Enter a valid e-mail address.']
->>> f.clean('foo@bar')
-Traceback (most recent call last):
-...
-ValidationError: [u'Enter a valid e-mail address.']
-
-EmailField also access min_length and max_length parameters, for convenience.
->>> f = EmailField(min_length=10, max_length=15)
->>> f.clean('a@foo.com')
-Traceback (most recent call last):
-...
-ValidationError: [u'Ensure this value has at least 10 characters (it has 9).']
->>> f.clean('alf@foo.com')
-u'alf@foo.com'
->>> f.clean('alf123456788@foo.com')
-Traceback (most recent call last):
-...
-ValidationError: [u'Ensure this value has at most 15 characters (it has 20).']
-
-# FileField ##################################################################
-
->>> f = FileField()
->>> f.clean('')
-Traceback (most recent call last):
-...
-ValidationError: [u'This field is required.']
-
->>> f.clean(None)
-Traceback (most recent call last):
-...
-ValidationError: [u'This field is required.']
-
->>> f.clean({})
-Traceback (most recent call last):
-...
-ValidationError: [u'No file was submitted.']
-
->>> f.clean('some content that is not a file')
-Traceback (most recent call last):
-...
-ValidationError: [u'No file was submitted. Check the encoding type on the form.']
-
->>> f.clean({'filename': 'name', 'content':None})
-Traceback (most recent call last):
-...
-ValidationError: [u'The submitted file is empty.']
-
->>> f.clean({'filename': 'name', 'content':''})
-Traceback (most recent call last):
-...
-ValidationError: [u'The submitted file is empty.']
-
->>> type(f.clean({'filename': 'name', 'content':'Some File Content'}))
-
-
-# URLField ##################################################################
-
->>> f = URLField()
->>> f.clean('')
-Traceback (most recent call last):
-...
-ValidationError: [u'This field is required.']
->>> f.clean(None)
-Traceback (most recent call last):
-...
-ValidationError: [u'This field is required.']
->>> f.clean('http://localhost')
-u'http://localhost'
->>> f.clean('http://example.com')
-u'http://example.com'
->>> f.clean('http://www.example.com')
-u'http://www.example.com'
->>> f.clean('http://www.example.com:8000/test')
-u'http://www.example.com:8000/test'
->>> f.clean('http://200.8.9.10')
-u'http://200.8.9.10'
->>> f.clean('http://200.8.9.10:8000/test')
-u'http://200.8.9.10:8000/test'
->>> f.clean('foo')
-Traceback (most recent call last):
-...
-ValidationError: [u'Enter a valid URL.']
->>> f.clean('http://')
-Traceback (most recent call last):
-...
-ValidationError: [u'Enter a valid URL.']
->>> f.clean('http://example')
-Traceback (most recent call last):
-...
-ValidationError: [u'Enter a valid URL.']
->>> f.clean('http://example.')
-Traceback (most recent call last):
-...
-ValidationError: [u'Enter a valid URL.']
->>> f.clean('http://.com')
-Traceback (most recent call last):
-...
-ValidationError: [u'Enter a valid URL.']
-
->>> f = URLField(required=False)
->>> f.clean('')
-u''
->>> f.clean(None)
-u''
->>> f.clean('http://example.com')
-u'http://example.com'
->>> f.clean('http://www.example.com')
-u'http://www.example.com'
->>> f.clean('foo')
-Traceback (most recent call last):
-...
-ValidationError: [u'Enter a valid URL.']
->>> f.clean('http://')
-Traceback (most recent call last):
-...
-ValidationError: [u'Enter a valid URL.']
->>> f.clean('http://example')
-Traceback (most recent call last):
-...
-ValidationError: [u'Enter a valid URL.']
->>> f.clean('http://example.')
-Traceback (most recent call last):
-...
-ValidationError: [u'Enter a valid URL.']
->>> f.clean('http://.com')
-Traceback (most recent call last):
-...
-ValidationError: [u'Enter a valid URL.']
-
-URLField takes an optional verify_exists parameter, which is False by default.
-This verifies that the URL is live on the Internet and doesn't return a 404 or 500:
->>> f = URLField(verify_exists=True)
->>> f.clean('http://www.google.com') # This will fail if there's no Internet connection
-u'http://www.google.com'
->>> f.clean('http://example')
-Traceback (most recent call last):
-...
-ValidationError: [u'Enter a valid URL.']
->>> f.clean('http://www.jfoiwjfoi23jfoijoaijfoiwjofiwjefewl.com') # bad domain
-Traceback (most recent call last):
-...
-ValidationError: [u'This URL appears to be a broken link.']
->>> f.clean('http://google.com/we-love-microsoft.html') # good domain, bad page
-Traceback (most recent call last):
-...
-ValidationError: [u'This URL appears to be a broken link.']
->>> f = URLField(verify_exists=True, required=False)
->>> f.clean('')
-u''
->>> f.clean('http://www.google.com') # This will fail if there's no Internet connection
-u'http://www.google.com'
-
-URLField also access min_length and max_length parameters, for convenience.
->>> f = URLField(min_length=15, max_length=20)
->>> f.clean('http://f.com')
-Traceback (most recent call last):
-...
-ValidationError: [u'Ensure this value has at least 15 characters (it has 12).']
->>> f.clean('http://example.com')
-u'http://example.com'
->>> f.clean('http://abcdefghijklmnopqrstuvwxyz.com')
-Traceback (most recent call last):
-...
-ValidationError: [u'Ensure this value has at most 20 characters (it has 37).']
-
-URLField should prepend 'http://' if no scheme was given
->>> f = URLField(required=False)
->>> f.clean('example.com')
-u'http://example.com'
->>> f.clean('')
-u''
->>> f.clean('https://example.com')
-u'https://example.com'
-
-# BooleanField ################################################################
-
->>> f = BooleanField()
->>> f.clean('')
-Traceback (most recent call last):
-...
-ValidationError: [u'This field is required.']
->>> f.clean(None)
-Traceback (most recent call last):
-...
-ValidationError: [u'This field is required.']
->>> f.clean(True)
-True
->>> f.clean(False)
-False
->>> f.clean(1)
-True
->>> f.clean(0)
-False
->>> f.clean('Django rocks')
-True
-
->>> f = BooleanField(required=False)
->>> f.clean('')
-False
->>> f.clean(None)
-False
->>> f.clean(True)
-True
->>> f.clean(False)
-False
->>> f.clean(1)
-True
->>> f.clean(0)
-False
->>> f.clean('Django rocks')
-True
-
-# ChoiceField #################################################################
-
->>> f = ChoiceField(choices=[('1', '1'), ('2', '2')])
->>> f.clean('')
-Traceback (most recent call last):
-...
-ValidationError: [u'This field is required.']
->>> f.clean(None)
-Traceback (most recent call last):
-...
-ValidationError: [u'This field is required.']
->>> f.clean(1)
-u'1'
->>> f.clean('1')
-u'1'
->>> f.clean('3')
-Traceback (most recent call last):
-...
-ValidationError: [u'Select a valid choice. That choice is not one of the available choices.']
-
->>> f = ChoiceField(choices=[('1', '1'), ('2', '2')], required=False)
->>> f.clean('')
-u''
->>> f.clean(None)
-u''
->>> f.clean(1)
-u'1'
->>> f.clean('1')
-u'1'
->>> f.clean('3')
-Traceback (most recent call last):
-...
-ValidationError: [u'Select a valid choice. That choice is not one of the available choices.']
-
->>> f = ChoiceField(choices=[('J', 'John'), ('P', 'Paul')])
->>> f.clean('J')
-u'J'
->>> f.clean('John')
-Traceback (most recent call last):
-...
-ValidationError: [u'Select a valid choice. That choice is not one of the available choices.']
-
-# NullBooleanField ############################################################
-
->>> f = NullBooleanField()
->>> f.clean('')
->>> f.clean(True)
-True
->>> f.clean(False)
-False
->>> f.clean(None)
->>> f.clean('1')
->>> f.clean('2')
->>> f.clean('3')
->>> f.clean('hello')
-
-# MultipleChoiceField #########################################################
-
->>> f = MultipleChoiceField(choices=[('1', '1'), ('2', '2')])
->>> f.clean('')
-Traceback (most recent call last):
-...
-ValidationError: [u'This field is required.']
->>> f.clean(None)
-Traceback (most recent call last):
-...
-ValidationError: [u'This field is required.']
->>> f.clean([1])
-[u'1']
->>> f.clean(['1'])
-[u'1']
->>> f.clean(['1', '2'])
-[u'1', u'2']
->>> f.clean([1, '2'])
-[u'1', u'2']
->>> f.clean((1, '2'))
-[u'1', u'2']
->>> f.clean('hello')
-Traceback (most recent call last):
-...
-ValidationError: [u'Enter a list of values.']
->>> f.clean([])
-Traceback (most recent call last):
-...
-ValidationError: [u'This field is required.']
->>> f.clean(())
-Traceback (most recent call last):
-...
-ValidationError: [u'This field is required.']
->>> f.clean(['3'])
-Traceback (most recent call last):
-...
-ValidationError: [u'Select a valid choice. 3 is not one of the available choices.']
-
->>> f = MultipleChoiceField(choices=[('1', '1'), ('2', '2')], required=False)
->>> f.clean('')
-[]
->>> f.clean(None)
-[]
->>> f.clean([1])
-[u'1']
->>> f.clean(['1'])
-[u'1']
->>> f.clean(['1', '2'])
-[u'1', u'2']
->>> f.clean([1, '2'])
-[u'1', u'2']
->>> f.clean((1, '2'))
-[u'1', u'2']
->>> f.clean('hello')
-Traceback (most recent call last):
-...
-ValidationError: [u'Enter a list of values.']
->>> f.clean([])
-[]
->>> f.clean(())
-[]
->>> f.clean(['3'])
-Traceback (most recent call last):
-...
-ValidationError: [u'Select a valid choice. 3 is not one of the available choices.']
-
-# ComboField ##################################################################
-
-ComboField takes a list of fields that should be used to validate a value,
-in that order.
->>> f = ComboField(fields=[CharField(max_length=20), EmailField()])
->>> f.clean('test@example.com')
-u'test@example.com'
->>> f.clean('longemailaddress@example.com')
-Traceback (most recent call last):
-...
-ValidationError: [u'Ensure this value has at most 20 characters (it has 28).']
->>> f.clean('not an e-mail')
-Traceback (most recent call last):
-...
-ValidationError: [u'Enter a valid e-mail address.']
->>> f.clean('')
-Traceback (most recent call last):
-...
-ValidationError: [u'This field is required.']
->>> f.clean(None)
-Traceback (most recent call last):
-...
-ValidationError: [u'This field is required.']
-
->>> f = ComboField(fields=[CharField(max_length=20), EmailField()], required=False)
->>> f.clean('test@example.com')
-u'test@example.com'
->>> f.clean('longemailaddress@example.com')
-Traceback (most recent call last):
-...
-ValidationError: [u'Ensure this value has at most 20 characters (it has 28).']
->>> f.clean('not an e-mail')
-Traceback (most recent call last):
-...
-ValidationError: [u'Enter a valid e-mail address.']
->>> f.clean('')
-u''
->>> f.clean(None)
-u''
-
-# SplitDateTimeField ##########################################################
-
->>> f = SplitDateTimeField()
->>> f.clean([datetime.date(2006, 1, 10), datetime.time(7, 30)])
-datetime.datetime(2006, 1, 10, 7, 30)
->>> f.clean(None)
-Traceback (most recent call last):
-...
-ValidationError: [u'This field is required.']
->>> f.clean('')
-Traceback (most recent call last):
-...
-ValidationError: [u'This field is required.']
->>> f.clean('hello')
-Traceback (most recent call last):
-...
-ValidationError: [u'Enter a list of values.']
->>> f.clean(['hello', 'there'])
-Traceback (most recent call last):
-...
-ValidationError: [u'Enter a valid date.', u'Enter a valid time.']
->>> f.clean(['2006-01-10', 'there'])
-Traceback (most recent call last):
-...
-ValidationError: [u'Enter a valid time.']
->>> f.clean(['hello', '07:30'])
-Traceback (most recent call last):
-...
-ValidationError: [u'Enter a valid date.']
-
->>> f = SplitDateTimeField(required=False)
->>> f.clean([datetime.date(2006, 1, 10), datetime.time(7, 30)])
-datetime.datetime(2006, 1, 10, 7, 30)
->>> f.clean(['2006-01-10', '07:30'])
-datetime.datetime(2006, 1, 10, 7, 30)
->>> f.clean(None)
->>> f.clean('')
->>> f.clean([''])
->>> f.clean(['', ''])
->>> f.clean('hello')
-Traceback (most recent call last):
-...
-ValidationError: [u'Enter a list of values.']
->>> f.clean(['hello', 'there'])
-Traceback (most recent call last):
-...
-ValidationError: [u'Enter a valid date.', u'Enter a valid time.']
->>> f.clean(['2006-01-10', 'there'])
-Traceback (most recent call last):
-...
-ValidationError: [u'Enter a valid time.']
->>> f.clean(['hello', '07:30'])
-Traceback (most recent call last):
-...
-ValidationError: [u'Enter a valid date.']
->>> f.clean(['2006-01-10', ''])
-Traceback (most recent call last):
-...
-ValidationError: [u'Enter a valid time.']
->>> f.clean(['2006-01-10'])
-Traceback (most recent call last):
-...
-ValidationError: [u'Enter a valid time.']
->>> f.clean(['', '07:30'])
-Traceback (most recent call last):
-...
-ValidationError: [u'Enter a valid date.']
-
-#########
-# Forms #
-#########
-
-A Form is a collection of Fields. It knows how to validate a set of data and it
-knows how to render itself in a couple of default ways (e.g., an HTML table).
-You can pass it data in __init__(), as a dictionary.
-
-# Form ########################################################################
-
->>> class Person(Form):
-... first_name = CharField()
-... last_name = CharField()
-... birthday = DateField()
-
-Pass a dictionary to a Form's __init__().
->>> p = Person({'first_name': u'John', 'last_name': u'Lennon', 'birthday': u'1940-10-9'})
->>> p.is_bound
-True
->>> p.errors
-{}
->>> p.is_valid()
-True
->>> p.errors.as_ul()
-u''
->>> p.errors.as_text()
-u''
->>> p.cleaned_data
-{'first_name': u'John', 'last_name': u'Lennon', 'birthday': datetime.date(1940, 10, 9)}
->>> print p['first_name']
-
->>> print p['last_name']
-
->>> print p['birthday']
-
->>> print p['nonexistentfield']
-Traceback (most recent call last):
-...
-KeyError: "Key 'nonexistentfield' not found in Form"
-
->>> for boundfield in p:
-... print boundfield
-
-
-
->>> for boundfield in p:
-... print boundfield.label, boundfield.data
-First name John
-Last name Lennon
-Birthday 1940-10-9
->>> print p
-
-
-
-
-Empty dictionaries are valid, too.
->>> p = Person({})
->>> p.is_bound
-True
->>> p.errors
-{'first_name': [u'This field is required.'], 'last_name': [u'This field is required.'], 'birthday': [u'This field is required.']}
->>> p.is_valid()
-False
->>> p.cleaned_data
-Traceback (most recent call last):
-...
-AttributeError: 'Person' object has no attribute 'cleaned_data'
->>> print p
-
This field is required.
-
This field is required.
-
This field is required.
->>> print p.as_table()
-
This field is required.
-
This field is required.
-
This field is required.
->>> print p.as_ul()
-
This field is required.
-
This field is required.
-
This field is required.
->>> print p.as_p()
-
This field is required.
-
-
This field is required.
-
-
This field is required.
-
-
-If you don't pass any values to the Form's __init__(), or if you pass None,
-the Form will be considered unbound and won't do any validation. Form.errors
-will be an empty dictionary *but* Form.is_valid() will return False.
->>> p = Person()
->>> p.is_bound
-False
->>> p.errors
-{}
->>> p.is_valid()
-False
->>> p.cleaned_data
-Traceback (most recent call last):
-...
-AttributeError: 'Person' object has no attribute 'cleaned_data'
->>> print p
-
-
-
->>> print p.as_table()
-
-
-
->>> print p.as_ul()
-
-
-
->>> print p.as_p()
-
-
-
-
-Unicode values are handled properly.
->>> p = Person({'first_name': u'John', 'last_name': u'\u0160\u0110\u0106\u017d\u0107\u017e\u0161\u0111', 'birthday': '1940-10-9'})
->>> p.as_table()
-u'
\n
\n
'
->>> p.as_ul()
-u'
\n
\n
'
->>> p.as_p()
-u'
\n
\n
'
-
->>> p = Person({'last_name': u'Lennon'})
->>> p.errors
-{'first_name': [u'This field is required.'], 'birthday': [u'This field is required.']}
->>> p.is_valid()
-False
->>> p.errors.as_ul()
-u'
first_name
This field is required.
birthday
This field is required.
'
->>> print p.errors.as_text()
-* first_name
- * This field is required.
-* birthday
- * This field is required.
->>> p.cleaned_data
-Traceback (most recent call last):
-...
-AttributeError: 'Person' object has no attribute 'cleaned_data'
->>> p['first_name'].errors
-[u'This field is required.']
->>> p['first_name'].errors.as_ul()
-u'
This field is required.
'
->>> p['first_name'].errors.as_text()
-u'* This field is required.'
-
->>> p = Person()
->>> print p['first_name']
-
->>> print p['last_name']
-
->>> print p['birthday']
-
-
-cleaned_data will always *only* contain a key for fields defined in the
-Form, even if you pass extra data when you define the Form. In this
-example, we pass a bunch of extra fields to the form constructor,
-but cleaned_data contains only the form's fields.
->>> data = {'first_name': u'John', 'last_name': u'Lennon', 'birthday': u'1940-10-9', 'extra1': 'hello', 'extra2': 'hello'}
->>> p = Person(data)
->>> p.is_valid()
-True
->>> p.cleaned_data
-{'first_name': u'John', 'last_name': u'Lennon', 'birthday': datetime.date(1940, 10, 9)}
-
-cleaned_data will include a key and value for *all* fields defined in the Form,
-even if the Form's data didn't include a value for fields that are not
-required. In this example, the data dictionary doesn't include a value for the
-"nick_name" field, but cleaned_data includes it. For CharFields, it's set to the
-empty string.
->>> class OptionalPersonForm(Form):
-... first_name = CharField()
-... last_name = CharField()
-... nick_name = CharField(required=False)
->>> data = {'first_name': u'John', 'last_name': u'Lennon'}
->>> f = OptionalPersonForm(data)
->>> f.is_valid()
-True
->>> f.cleaned_data
-{'nick_name': u'', 'first_name': u'John', 'last_name': u'Lennon'}
-
-For DateFields, it's set to None.
->>> class OptionalPersonForm(Form):
-... first_name = CharField()
-... last_name = CharField()
-... birth_date = DateField(required=False)
->>> data = {'first_name': u'John', 'last_name': u'Lennon'}
->>> f = OptionalPersonForm(data)
->>> f.is_valid()
-True
->>> f.cleaned_data
-{'birth_date': None, 'first_name': u'John', 'last_name': u'Lennon'}
-
-"auto_id" tells the Form to add an "id" attribute to each form element.
-If it's a string that contains '%s', Django will use that as a format string
-into which the field's name will be inserted. It will also put a
-
-MultipleChoiceField is a special case, as its data is required to be a list:
->>> class SongForm(Form):
-... name = CharField()
-... composers = MultipleChoiceField()
->>> f = SongForm(auto_id=False)
->>> print f['composers']
-
->>> class SongForm(Form):
-... name = CharField()
-... composers = MultipleChoiceField(choices=[('J', 'John Lennon'), ('P', 'Paul McCartney')])
->>> f = SongForm(auto_id=False)
->>> print f['composers']
-
->>> f = SongForm({'name': 'Yesterday', 'composers': ['P']}, auto_id=False)
->>> print f['name']
-
->>> print f['composers']
-
-
-MultipleChoiceField rendered as_hidden() is a special case. Because it can
-have multiple values, its as_hidden() renders multiple
-tags.
->>> f = SongForm({'name': 'Yesterday', 'composers': ['P']}, auto_id=False)
->>> print f['composers'].as_hidden()
-
->>> f = SongForm({'name': 'From Me To You', 'composers': ['P', 'J']}, auto_id=False)
->>> print f['composers'].as_hidden()
-
-
-
-MultipleChoiceField can also be used with the CheckboxSelectMultiple widget.
->>> class SongForm(Form):
-... name = CharField()
-... composers = MultipleChoiceField(choices=[('J', 'John Lennon'), ('P', 'Paul McCartney')], widget=CheckboxSelectMultiple)
->>> f = SongForm(auto_id=False)
->>> print f['composers']
-
-
John Lennon
-
Paul McCartney
-
->>> f = SongForm({'composers': ['J']}, auto_id=False)
->>> print f['composers']
-
-
-Regarding auto_id, CheckboxSelectMultiple is a special case. Each checkbox
-gets a distinct ID, formed by appending an underscore plus the checkbox's
-zero-based index.
->>> f = SongForm(auto_id='%s_id')
->>> print f['composers']
-
-
John Lennon
-
Paul McCartney
-
-
-Data for a MultipleChoiceField should be a list. QueryDict and MultiValueDict
-conveniently work with this.
->>> data = {'name': 'Yesterday', 'composers': ['J', 'P']}
->>> f = SongForm(data)
->>> f.errors
-{}
->>> from django.http import QueryDict
->>> data = QueryDict('name=Yesterday&composers=J&composers=P')
->>> f = SongForm(data)
->>> f.errors
-{}
->>> from django.utils.datastructures import MultiValueDict
->>> data = MultiValueDict(dict(name=['Yesterday'], composers=['J', 'P']))
->>> f = SongForm(data)
->>> f.errors
-{}
-
-The MultipleHiddenInput widget renders multiple values as hidden fields.
->>> class SongFormHidden(Form):
-... name = CharField()
-... composers = MultipleChoiceField(choices=[('J', 'John Lennon'), ('P', 'Paul McCartney')], widget=MultipleHiddenInput)
->>> f = SongFormHidden(MultiValueDict(dict(name=['Yesterday'], composers=['J', 'P'])), auto_id=False)
->>> print f.as_ul()
-
Name:
-
-
-When using CheckboxSelectMultiple, the framework expects a list of input and
-returns a list of input.
->>> f = SongForm({'name': 'Yesterday'}, auto_id=False)
->>> f.errors
-{'composers': [u'This field is required.']}
->>> f = SongForm({'name': 'Yesterday', 'composers': ['J']}, auto_id=False)
->>> f.errors
-{}
->>> f.cleaned_data
-{'composers': [u'J'], 'name': u'Yesterday'}
->>> f = SongForm({'name': 'Yesterday', 'composers': ['J', 'P']}, auto_id=False)
->>> f.errors
-{}
->>> f.cleaned_data
-{'composers': [u'J', u'P'], 'name': u'Yesterday'}
-
-Validation errors are HTML-escaped when output as HTML.
->>> class EscapingForm(Form):
-... special_name = CharField()
-... def clean_special_name(self):
-... raise ValidationError("Something's wrong with '%s'" % self.cleaned_data['special_name'])
-
->>> f = EscapingForm({'special_name': "Nothing to escape"}, auto_id=False)
->>> print f
-
Special name:
Something's wrong with 'Nothing to escape'
->>> f = EscapingForm({'special_name': "Should escape < & > and "}, auto_id=False)
->>> print f
-
Special name:
Something's wrong with 'Should escape < & > and <script>alert('xss')</script>'
-
-# Validating multiple fields in relation to another ###########################
-
-There are a couple of ways to do multiple-field validation. If you want the
-validation message to be associated with a particular field, implement the
-clean_XXX() method on the Form, where XXX is the field name. As in
-Field.clean(), the clean_XXX() method should return the cleaned value. In the
-clean_XXX() method, you have access to self.cleaned_data, which is a dictionary
-of all the data that has been cleaned *so far*, in order by the fields,
-including the current field (e.g., the field XXX if you're in clean_XXX()).
->>> class UserRegistration(Form):
-... username = CharField(max_length=10)
-... password1 = CharField(widget=PasswordInput)
-... password2 = CharField(widget=PasswordInput)
-... def clean_password2(self):
-... if self.cleaned_data.get('password1') and self.cleaned_data.get('password2') and self.cleaned_data['password1'] != self.cleaned_data['password2']:
-... raise ValidationError(u'Please make sure your passwords match.')
-... return self.cleaned_data['password2']
->>> f = UserRegistration(auto_id=False)
->>> f.errors
-{}
->>> f = UserRegistration({}, auto_id=False)
->>> f.errors
-{'username': [u'This field is required.'], 'password1': [u'This field is required.'], 'password2': [u'This field is required.']}
->>> f = UserRegistration({'username': 'adrian', 'password1': 'foo', 'password2': 'bar'}, auto_id=False)
->>> f.errors
-{'password2': [u'Please make sure your passwords match.']}
->>> f = UserRegistration({'username': 'adrian', 'password1': 'foo', 'password2': 'foo'}, auto_id=False)
->>> f.errors
-{}
->>> f.cleaned_data
-{'username': u'adrian', 'password1': u'foo', 'password2': u'foo'}
-
-Another way of doing multiple-field validation is by implementing the
-Form's clean() method. If you do this, any ValidationError raised by that
-method will not be associated with a particular field; it will have a
-special-case association with the field named '__all__'.
-Note that in Form.clean(), you have access to self.cleaned_data, a dictionary of
-all the fields/values that have *not* raised a ValidationError. Also note
-Form.clean() is required to return a dictionary of all clean data.
->>> class UserRegistration(Form):
-... username = CharField(max_length=10)
-... password1 = CharField(widget=PasswordInput)
-... password2 = CharField(widget=PasswordInput)
-... def clean(self):
-... if self.cleaned_data.get('password1') and self.cleaned_data.get('password2') and self.cleaned_data['password1'] != self.cleaned_data['password2']:
-... raise ValidationError(u'Please make sure your passwords match.')
-... return self.cleaned_data
->>> f = UserRegistration(auto_id=False)
->>> f.errors
-{}
->>> f = UserRegistration({}, auto_id=False)
->>> print f.as_table()
-
Username:
This field is required.
-
Password1:
This field is required.
-
Password2:
This field is required.
->>> f.errors
-{'username': [u'This field is required.'], 'password1': [u'This field is required.'], 'password2': [u'This field is required.']}
->>> f = UserRegistration({'username': 'adrian', 'password1': 'foo', 'password2': 'bar'}, auto_id=False)
->>> f.errors
-{'__all__': [u'Please make sure your passwords match.']}
->>> print f.as_table()
-
Please make sure your passwords match.
-
Username:
-
Password1:
-
Password2:
->>> print f.as_ul()
-
Please make sure your passwords match.
-
Username:
-
Password1:
-
Password2:
->>> f = UserRegistration({'username': 'adrian', 'password1': 'foo', 'password2': 'foo'}, auto_id=False)
->>> f.errors
-{}
->>> f.cleaned_data
-{'username': u'adrian', 'password1': u'foo', 'password2': u'foo'}
-
-# Dynamic construction ########################################################
-
-It's possible to construct a Form dynamically by adding to the self.fields
-dictionary in __init__(). Don't forget to call Form.__init__() within the
-subclass' __init__().
->>> class Person(Form):
-... first_name = CharField()
-... last_name = CharField()
-... def __init__(self, *args, **kwargs):
-... super(Person, self).__init__(*args, **kwargs)
-... self.fields['birthday'] = DateField()
->>> p = Person(auto_id=False)
->>> print p
-
First name:
-
Last name:
-
Birthday:
-
-Instances of a dynamic Form do not persist fields from one Form instance to
-the next.
->>> class MyForm(Form):
-... def __init__(self, data=None, auto_id=False, field_list=[]):
-... Form.__init__(self, data, auto_id=auto_id)
-... for field in field_list:
-... self.fields[field[0]] = field[1]
->>> field_list = [('field1', CharField()), ('field2', CharField())]
->>> my_form = MyForm(field_list=field_list)
->>> print my_form
-
-
-Similarly, changes to field attributes do not persist from one Form instance
-to the next.
->>> class Person(Form):
-... first_name = CharField(required=False)
-... last_name = CharField(required=False)
-... def __init__(self, names_required=False, *args, **kwargs):
-... super(Person, self).__init__(*args, **kwargs)
-... if names_required:
-... self.fields['first_name'].required = True
-... self.fields['first_name'].widget.attrs['class'] = 'required'
-... self.fields['last_name'].required = True
-... self.fields['last_name'].widget.attrs['class'] = 'required'
->>> f = Person(names_required=False)
->>> f['first_name'].field.required, f['last_name'].field.required
-(False, False)
->>> f['first_name'].field.widget.attrs, f['last_name'].field.widget.attrs
-({}, {})
->>> f = Person(names_required=True)
->>> f['first_name'].field.required, f['last_name'].field.required
-(True, True)
->>> f['first_name'].field.widget.attrs, f['last_name'].field.widget.attrs
-({'class': 'required'}, {'class': 'required'})
->>> f = Person(names_required=False)
->>> f['first_name'].field.required, f['last_name'].field.required
-(False, False)
->>> f['first_name'].field.widget.attrs, f['last_name'].field.widget.attrs
-({}, {})
->>> class Person(Form):
-... first_name = CharField(max_length=30)
-... last_name = CharField(max_length=30)
-... def __init__(self, name_max_length=None, *args, **kwargs):
-... super(Person, self).__init__(*args, **kwargs)
-... if name_max_length:
-... self.fields['first_name'].max_length = name_max_length
-... self.fields['last_name'].max_length = name_max_length
->>> f = Person(name_max_length=None)
->>> f['first_name'].field.max_length, f['last_name'].field.max_length
-(30, 30)
->>> f = Person(name_max_length=20)
->>> f['first_name'].field.max_length, f['last_name'].field.max_length
-(20, 20)
->>> f = Person(name_max_length=None)
->>> f['first_name'].field.max_length, f['last_name'].field.max_length
-(30, 30)
-
-HiddenInput widgets are displayed differently in the as_table(), as_ul()
-and as_p() output of a Form -- their verbose names are not displayed, and a
-separate row is not displayed. They're displayed in the last row of the
-form, directly after that row's form element.
->>> class Person(Form):
-... first_name = CharField()
-... last_name = CharField()
-... hidden_text = CharField(widget=HiddenInput)
-... birthday = DateField()
->>> p = Person(auto_id=False)
->>> print p
-
First name:
-
Last name:
-
Birthday:
->>> print p.as_ul()
-
First name:
-
Last name:
-
Birthday:
->>> print p.as_p()
-
First name:
-
Last name:
-
Birthday:
-
-With auto_id set, a HiddenInput still gets an ID, but it doesn't get a label.
->>> p = Person(auto_id='id_%s')
->>> print p
-
First name:
-
Last name:
-
Birthday:
->>> print p.as_ul()
-
First name:
-
Last name:
-
Birthday:
->>> print p.as_p()
-
First name:
-
Last name:
-
Birthday:
-
-If a field with a HiddenInput has errors, the as_table() and as_ul() output
-will include the error message(s) with the text "(Hidden field [fieldname]) "
-prepended. This message is displayed at the top of the output, regardless of
-its field's order in the form.
->>> p = Person({'first_name': 'John', 'last_name': 'Lennon', 'birthday': '1940-10-9'}, auto_id=False)
->>> print p
-
(Hidden field hidden_text) This field is required.
-
First name:
-
Last name:
-
Birthday:
->>> print p.as_ul()
-
(Hidden field hidden_text) This field is required.
-
First name:
-
Last name:
-
Birthday:
->>> print p.as_p()
-
(Hidden field hidden_text) This field is required.
-
First name:
-
Last name:
-
Birthday:
-
-A corner case: It's possible for a form to have only HiddenInputs.
->>> class TestForm(Form):
-... foo = CharField(widget=HiddenInput)
-... bar = CharField(widget=HiddenInput)
->>> p = TestForm(auto_id=False)
->>> print p.as_table()
-
->>> print p.as_ul()
-
->>> print p.as_p()
-
-
-A Form's fields are displayed in the same order in which they were defined.
->>> class TestForm(Form):
-... field1 = CharField()
-... field2 = CharField()
-... field3 = CharField()
-... field4 = CharField()
-... field5 = CharField()
-... field6 = CharField()
-... field7 = CharField()
-... field8 = CharField()
-... field9 = CharField()
-... field10 = CharField()
-... field11 = CharField()
-... field12 = CharField()
-... field13 = CharField()
-... field14 = CharField()
->>> p = TestForm(auto_id=False)
->>> print p
-
Field1:
-
Field2:
-
Field3:
-
Field4:
-
Field5:
-
Field6:
-
Field7:
-
Field8:
-
Field9:
-
Field10:
-
Field11:
-
Field12:
-
Field13:
-
Field14:
-
-Some Field classes have an effect on the HTML attributes of their associated
-Widget. If you set max_length in a CharField and its associated widget is
-either a TextInput or PasswordInput, then the widget's rendered HTML will
-include the "maxlength" attribute.
->>> class UserRegistration(Form):
-... username = CharField(max_length=10) # uses TextInput by default
-... password = CharField(max_length=10, widget=PasswordInput)
-... realname = CharField(max_length=10, widget=TextInput) # redundantly define widget, just to test
-... address = CharField() # no max_length defined here
->>> p = UserRegistration(auto_id=False)
->>> print p.as_ul()
-
Username:
-
Password:
-
Realname:
-
Address:
-
-If you specify a custom "attrs" that includes the "maxlength" attribute,
-the Field's max_length attribute will override whatever "maxlength" you specify
-in "attrs".
->>> class UserRegistration(Form):
-... username = CharField(max_length=10, widget=TextInput(attrs={'maxlength': 20}))
-... password = CharField(max_length=10, widget=PasswordInput)
->>> p = UserRegistration(auto_id=False)
->>> print p.as_ul()
-
Username:
-
Password:
-
-# Specifying labels ###########################################################
-
-You can specify the label for a field by using the 'label' argument to a Field
-class. If you don't specify 'label', Django will use the field name with
-underscores converted to spaces, and the initial letter capitalized.
->>> class UserRegistration(Form):
-... username = CharField(max_length=10, label='Your username')
-... password1 = CharField(widget=PasswordInput)
-... password2 = CharField(widget=PasswordInput, label='Password (again)')
->>> p = UserRegistration(auto_id=False)
->>> print p.as_ul()
-
Your username:
-
Password1:
-
Password (again):
-
-Labels for as_* methods will only end in a colon if they don't end in other
-punctuation already.
->>> class Questions(Form):
-... q1 = CharField(label='The first question')
-... q2 = CharField(label='What is your name?')
-... q3 = CharField(label='The answer to life is:')
-... q4 = CharField(label='Answer this question!')
-... q5 = CharField(label='The last question. Period.')
->>> print Questions(auto_id=False).as_p()
-
The first question:
-
What is your name?
-
The answer to life is:
-
Answer this question!
-
The last question. Period.
->>> print Questions().as_p()
-
The first question:
-
What is your name?
-
The answer to life is:
-
Answer this question!
-
The last question. Period.
-
-A label can be a Unicode object or a bytestring with special characters.
->>> class UserRegistration(Form):
-... username = CharField(max_length=10, label='ŠĐĆŽćžšđ')
-... password = CharField(widget=PasswordInput, label=u'\u0160\u0110\u0106\u017d\u0107\u017e\u0161\u0111')
->>> p = UserRegistration(auto_id=False)
->>> p.as_ul()
-u'
\u0160\u0110\u0106\u017d\u0107\u017e\u0161\u0111:
\n
\u0160\u0110\u0106\u017d\u0107\u017e\u0161\u0111:
'
-
-If a label is set to the empty string for a field, that field won't get a label.
->>> class UserRegistration(Form):
-... username = CharField(max_length=10, label='')
-... password = CharField(widget=PasswordInput)
->>> p = UserRegistration(auto_id=False)
->>> print p.as_ul()
-
-
Password:
->>> p = UserRegistration(auto_id='id_%s')
->>> print p.as_ul()
-
-
Password:
-
-If label is None, Django will auto-create the label from the field name. This
-is default behavior.
->>> class UserRegistration(Form):
-... username = CharField(max_length=10, label=None)
-... password = CharField(widget=PasswordInput)
->>> p = UserRegistration(auto_id=False)
->>> print p.as_ul()
-
Username:
-
Password:
->>> p = UserRegistration(auto_id='id_%s')
->>> print p.as_ul()
-
Username:
-
Password:
-
-# Initial data ################################################################
-
-You can specify initial data for a field by using the 'initial' argument to a
-Field class. This initial data is displayed when a Form is rendered with *no*
-data. It is not displayed when a Form is rendered with any data (including an
-empty dictionary). Also, the initial value is *not* used if data for a
-particular required field isn't provided.
->>> class UserRegistration(Form):
-... username = CharField(max_length=10, initial='django')
-... password = CharField(widget=PasswordInput)
-
-Here, we're not submitting any data, so the initial value will be displayed.
->>> p = UserRegistration(auto_id=False)
->>> print p.as_ul()
-
Username:
-
Password:
-
-Here, we're submitting data, so the initial value will *not* be displayed.
->>> p = UserRegistration({}, auto_id=False)
->>> print p.as_ul()
-
This field is required.
Username:
-
This field is required.
Password:
->>> p = UserRegistration({'username': u''}, auto_id=False)
->>> print p.as_ul()
-
This field is required.
Username:
-
This field is required.
Password:
->>> p = UserRegistration({'username': u'foo'}, auto_id=False)
->>> print p.as_ul()
-
Username:
-
This field is required.
Password:
-
-An 'initial' value is *not* used as a fallback if data is not provided. In this
-example, we don't provide a value for 'username', and the form raises a
-validation error rather than using the initial value for 'username'.
->>> p = UserRegistration({'password': 'secret'})
->>> p.errors
-{'username': [u'This field is required.']}
->>> p.is_valid()
-False
-
-# Dynamic initial data ########################################################
-
-The previous technique dealt with "hard-coded" initial data, but it's also
-possible to specify initial data after you've already created the Form class
-(i.e., at runtime). Use the 'initial' parameter to the Form constructor. This
-should be a dictionary containing initial values for one or more fields in the
-form, keyed by field name.
-
->>> class UserRegistration(Form):
-... username = CharField(max_length=10)
-... password = CharField(widget=PasswordInput)
-
-Here, we're not submitting any data, so the initial value will be displayed.
->>> p = UserRegistration(initial={'username': 'django'}, auto_id=False)
->>> print p.as_ul()
-
Username:
-
Password:
->>> p = UserRegistration(initial={'username': 'stephane'}, auto_id=False)
->>> print p.as_ul()
-
Username:
-
Password:
-
-The 'initial' parameter is meaningless if you pass data.
->>> p = UserRegistration({}, initial={'username': 'django'}, auto_id=False)
->>> print p.as_ul()
-
-
-A dynamic 'initial' value is *not* used as a fallback if data is not provided.
-In this example, we don't provide a value for 'username', and the form raises a
-validation error rather than using the initial value for 'username'.
->>> p = UserRegistration({'password': 'secret'}, initial={'username': 'django'})
->>> p.errors
-{'username': [u'This field is required.']}
->>> p.is_valid()
-False
-
-If a Form defines 'initial' *and* 'initial' is passed as a parameter to Form(),
-then the latter will get precedence.
->>> class UserRegistration(Form):
-... username = CharField(max_length=10, initial='django')
-... password = CharField(widget=PasswordInput)
->>> p = UserRegistration(initial={'username': 'babik'}, auto_id=False)
->>> print p.as_ul()
-
Username:
-
Password:
-
-# Callable initial data ########################################################
-
-The previous technique dealt with raw values as initial data, but it's also
-possible to specify callable data.
-
->>> class UserRegistration(Form):
-... username = CharField(max_length=10)
-... password = CharField(widget=PasswordInput)
-
-We need to define functions that get called later.
->>> def initial_django():
-... return 'django'
->>> def initial_stephane():
-... return 'stephane'
-
-Here, we're not submitting any data, so the initial value will be displayed.
->>> p = UserRegistration(initial={'username': initial_django}, auto_id=False)
->>> print p.as_ul()
-
Username:
-
Password:
-
-The 'initial' parameter is meaningless if you pass data.
->>> p = UserRegistration({}, initial={'username': initial_django}, auto_id=False)
->>> print p.as_ul()
-
-
-A callable 'initial' value is *not* used as a fallback if data is not provided.
-In this example, we don't provide a value for 'username', and the form raises a
-validation error rather than using the initial value for 'username'.
->>> p = UserRegistration({'password': 'secret'}, initial={'username': initial_django})
->>> p.errors
-{'username': [u'This field is required.']}
->>> p.is_valid()
-False
-
-If a Form defines 'initial' *and* 'initial' is passed as a parameter to Form(),
-then the latter will get precedence.
->>> class UserRegistration(Form):
-... username = CharField(max_length=10, initial=initial_django)
-... password = CharField(widget=PasswordInput)
->>> p = UserRegistration(auto_id=False)
->>> print p.as_ul()
-
Username:
-
Password:
->>> p = UserRegistration(initial={'username': initial_stephane}, auto_id=False)
->>> print p.as_ul()
-
Username:
-
Password:
-
-# Help text ###################################################################
-
-You can specify descriptive text for a field by using the 'help_text' argument
-to a Field class. This help text is displayed when a Form is rendered.
->>> class UserRegistration(Form):
-... username = CharField(max_length=10, help_text='e.g., user@example.com')
-... password = CharField(widget=PasswordInput, help_text='Choose wisely.')
->>> p = UserRegistration(auto_id=False)
->>> print p.as_ul()
-
Username: e.g., user@example.com
-
Password: Choose wisely.
->>> print p.as_p()
-
Username: e.g., user@example.com
-
Password: Choose wisely.
->>> print p.as_table()
-
Username:
e.g., user@example.com
-
Password:
Choose wisely.
-
-The help text is displayed whether or not data is provided for the form.
->>> p = UserRegistration({'username': u'foo'}, auto_id=False)
->>> print p.as_ul()
-
Username: e.g., user@example.com
-
This field is required.
Password: Choose wisely.
-
-help_text is not displayed for hidden fields. It can be used for documentation
-purposes, though.
->>> class UserRegistration(Form):
-... username = CharField(max_length=10, help_text='e.g., user@example.com')
-... password = CharField(widget=PasswordInput)
-... next = CharField(widget=HiddenInput, initial='/', help_text='Redirect destination')
->>> p = UserRegistration(auto_id=False)
->>> print p.as_ul()
-
Username: e.g., user@example.com
-
Password:
-
-Help text can include arbitrary Unicode characters.
->>> class UserRegistration(Form):
-... username = CharField(max_length=10, help_text='ŠĐĆŽćžšđ')
->>> p = UserRegistration(auto_id=False)
->>> p.as_ul()
-u'
'
-
-# Subclassing forms ###########################################################
-
-You can subclass a Form to add fields. The resulting form subclass will have
-all of the fields of the parent Form, plus whichever fields you define in the
-subclass.
->>> class Person(Form):
-... first_name = CharField()
-... last_name = CharField()
-... birthday = DateField()
->>> class Musician(Person):
-... instrument = CharField()
->>> p = Person(auto_id=False)
->>> print p.as_ul()
-
First name:
-
Last name:
-
Birthday:
->>> m = Musician(auto_id=False)
->>> print m.as_ul()
-
First name:
-
Last name:
-
Birthday:
-
Instrument:
-
-Yes, you can subclass multiple forms. The fields are added in the order in
-which the parent classes are listed.
->>> class Person(Form):
-... first_name = CharField()
-... last_name = CharField()
-... birthday = DateField()
->>> class Instrument(Form):
-... instrument = CharField()
->>> class Beatle(Person, Instrument):
-... haircut_type = CharField()
->>> b = Beatle(auto_id=False)
->>> print b.as_ul()
-
First name:
-
Last name:
-
Birthday:
-
Instrument:
-
Haircut type:
-
-# Forms with prefixes #########################################################
-
-Sometimes it's necessary to have multiple forms display on the same HTML page,
-or multiple copies of the same form. We can accomplish this with form prefixes.
-Pass the keyword argument 'prefix' to the Form constructor to use this feature.
-This value will be prepended to each HTML form field name. One way to think
-about this is "namespaces for HTML forms". Notice that in the data argument,
-each field's key has the prefix, in this case 'person1', prepended to the
-actual field name.
->>> class Person(Form):
-... first_name = CharField()
-... last_name = CharField()
-... birthday = DateField()
->>> data = {
-... 'person1-first_name': u'John',
-... 'person1-last_name': u'Lennon',
-... 'person1-birthday': u'1940-10-9'
-... }
->>> p = Person(data, prefix='person1')
->>> print p.as_ul()
-
First name:
-
Last name:
-
Birthday:
->>> print p['first_name']
-
->>> print p['last_name']
-
->>> print p['birthday']
-
->>> p.errors
-{}
->>> p.is_valid()
-True
->>> p.cleaned_data
-{'first_name': u'John', 'last_name': u'Lennon', 'birthday': datetime.date(1940, 10, 9)}
-
-Let's try submitting some bad data to make sure form.errors and field.errors
-work as expected.
->>> data = {
-... 'person1-first_name': u'',
-... 'person1-last_name': u'',
-... 'person1-birthday': u''
-... }
->>> p = Person(data, prefix='person1')
->>> p.errors
-{'first_name': [u'This field is required.'], 'last_name': [u'This field is required.'], 'birthday': [u'This field is required.']}
->>> p['first_name'].errors
-[u'This field is required.']
->>> p['person1-first_name'].errors
-Traceback (most recent call last):
-...
-KeyError: "Key 'person1-first_name' not found in Form"
-
-In this example, the data doesn't have a prefix, but the form requires it, so
-the form doesn't "see" the fields.
->>> data = {
-... 'first_name': u'John',
-... 'last_name': u'Lennon',
-... 'birthday': u'1940-10-9'
-... }
->>> p = Person(data, prefix='person1')
->>> p.errors
-{'first_name': [u'This field is required.'], 'last_name': [u'This field is required.'], 'birthday': [u'This field is required.']}
-
-With prefixes, a single data dictionary can hold data for multiple instances
-of the same form.
->>> data = {
-... 'person1-first_name': u'John',
-... 'person1-last_name': u'Lennon',
-... 'person1-birthday': u'1940-10-9',
-... 'person2-first_name': u'Jim',
-... 'person2-last_name': u'Morrison',
-... 'person2-birthday': u'1943-12-8'
-... }
->>> p1 = Person(data, prefix='person1')
->>> p1.is_valid()
-True
->>> p1.cleaned_data
-{'first_name': u'John', 'last_name': u'Lennon', 'birthday': datetime.date(1940, 10, 9)}
->>> p2 = Person(data, prefix='person2')
->>> p2.is_valid()
-True
->>> p2.cleaned_data
-{'first_name': u'Jim', 'last_name': u'Morrison', 'birthday': datetime.date(1943, 12, 8)}
-
-By default, forms append a hyphen between the prefix and the field name, but a
-form can alter that behavior by implementing the add_prefix() method. This
-method takes a field name and returns the prefixed field, according to
-self.prefix.
->>> class Person(Form):
-... first_name = CharField()
-... last_name = CharField()
-... birthday = DateField()
-... def add_prefix(self, field_name):
-... return self.prefix and '%s-prefix-%s' % (self.prefix, field_name) or field_name
->>> p = Person(prefix='foo')
->>> print p.as_ul()
-
First name:
-
Last name:
-
Birthday:
->>> data = {
-... 'foo-prefix-first_name': u'John',
-... 'foo-prefix-last_name': u'Lennon',
-... 'foo-prefix-birthday': u'1940-10-9'
-... }
->>> p = Person(data, prefix='foo')
->>> p.is_valid()
-True
->>> p.cleaned_data
-{'first_name': u'John', 'last_name': u'Lennon', 'birthday': datetime.date(1940, 10, 9)}
-
-# Forms with NullBooleanFields ################################################
-
-NullBooleanField is a bit of a special case because its presentation (widget)
-is different than its data. This is handled transparently, though.
-
->>> class Person(Form):
-... name = CharField()
-... is_cool = NullBooleanField()
->>> p = Person({'name': u'Joe'}, auto_id=False)
->>> print p['is_cool']
-
->>> p = Person({'name': u'Joe', 'is_cool': u'1'}, auto_id=False)
->>> print p['is_cool']
-
->>> p = Person({'name': u'Joe', 'is_cool': u'2'}, auto_id=False)
->>> print p['is_cool']
-
->>> p = Person({'name': u'Joe', 'is_cool': u'3'}, auto_id=False)
->>> print p['is_cool']
-
->>> p = Person({'name': u'Joe', 'is_cool': True}, auto_id=False)
->>> print p['is_cool']
-
->>> p = Person({'name': u'Joe', 'is_cool': False}, auto_id=False)
->>> print p['is_cool']
-
-
-# Forms with FileFields ################################################
-
-FileFields are a special case because they take their data from the request.FILES,
-not request.POST.
-
->>> class FileForm(Form):
-... file1 = FileField()
->>> f = FileForm(auto_id=False)
->>> print f
-
File1:
-
->>> f = FileForm(data={}, files={}, auto_id=False)
->>> print f
-
File1:
This field is required.
-
->>> f = FileForm(data={}, files={'file1': {'filename': 'name', 'content':''}}, auto_id=False)
->>> print f
-
File1:
The submitted file is empty.
-
->>> f = FileForm(data={}, files={'file1': 'something that is not a file'}, auto_id=False)
->>> print f
-
File1:
No file was submitted. Check the encoding type on the form.
-
->>> f = FileForm(data={}, files={'file1': {'filename': 'name', 'content':'some content'}}, auto_id=False)
->>> print f
-
File1:
->>> f.is_valid()
-True
-
-# Basic form processing in a view #############################################
-
->>> from django.template import Template, Context
->>> class UserRegistration(Form):
-... username = CharField(max_length=10)
-... password1 = CharField(widget=PasswordInput)
-... password2 = CharField(widget=PasswordInput)
-... def clean(self):
-... if self.cleaned_data.get('password1') and self.cleaned_data.get('password2') and self.cleaned_data['password1'] != self.cleaned_data['password2']:
-... raise ValidationError(u'Please make sure your passwords match.')
-... return self.cleaned_data
->>> def my_function(method, post_data):
-... if method == 'POST':
-... form = UserRegistration(post_data, auto_id=False)
-... else:
-... form = UserRegistration(auto_id=False)
-... if form.is_valid():
-... return 'VALID: %r' % form.cleaned_data
-... t = Template('')
-... return t.render(Context({'form': form}))
-
-Case 1: GET (an empty form, with no errors).
->>> print my_function('GET', {})
-
-
-Case 2: POST with erroneous data (a redisplayed form, with errors).
->>> print my_function('POST', {'username': 'this-is-a-long-username', 'password1': 'foo', 'password2': 'bar'})
-
-
-Case 3: POST with valid data (the success message).
->>> print my_function('POST', {'username': 'adrian', 'password1': 'secret', 'password2': 'secret'})
-VALID: {'username': u'adrian', 'password1': u'secret', 'password2': u'secret'}
-
-# Some ideas for using templates with forms ###################################
-
->>> class UserRegistration(Form):
-... username = CharField(max_length=10, help_text="Good luck picking a username that doesn't already exist.")
-... password1 = CharField(widget=PasswordInput)
-... password2 = CharField(widget=PasswordInput)
-... def clean(self):
-... if self.cleaned_data.get('password1') and self.cleaned_data.get('password2') and self.cleaned_data['password1'] != self.cleaned_data['password2']:
-... raise ValidationError(u'Please make sure your passwords match.')
-... return self.cleaned_data
-
-You have full flexibility in displaying form fields in a template. Just pass a
-Form instance to the template, and use "dot" access to refer to individual
-fields. Note, however, that this flexibility comes with the responsibility of
-displaying all the errors, including any that might not be associated with a
-particular field.
->>> t = Template('''''')
->>> print t.render(Context({'form': UserRegistration(auto_id=False)}))
-
->>> print t.render(Context({'form': UserRegistration({'username': 'django'}, auto_id=False)}))
-
-
-Use form.[field].label to output a field's label. You can specify the label for
-a field by using the 'label' argument to a Field class. If you don't specify
-'label', Django will use the field name with underscores converted to spaces,
-and the initial letter capitalized.
->>> t = Template('''''')
->>> print t.render(Context({'form': UserRegistration(auto_id=False)}))
-
-
-User form.[field].label_tag to output a field's label with a tag
-wrapped around it, but *only* if the given field has an "id" attribute.
-Recall from above that passing the "auto_id" argument to a Form gives each
-field an "id" attribute.
->>> t = Template('''''')
->>> print t.render(Context({'form': UserRegistration(auto_id=False)}))
-
->>> print t.render(Context({'form': UserRegistration(auto_id='id_%s')}))
-
-
-User form.[field].help_text to output a field's help text. If the given field
-does not have help text, nothing will be output.
->>> t = Template('''''')
->>> print t.render(Context({'form': UserRegistration(auto_id=False)}))
-
->>> Template('{{ form.password1.help_text }}').render(Context({'form': UserRegistration(auto_id=False)}))
-u''
-
-The label_tag() method takes an optional attrs argument: a dictionary of HTML
-attributes to add to the tag.
->>> f = UserRegistration(auto_id='id_%s')
->>> for bf in f:
-... print bf.label_tag(attrs={'class': 'pretty'})
-Username
-Password1
-Password2
-
-To display the errors that aren't associated with a particular field -- e.g.,
-the errors caused by Form.clean() -- use {{ form.non_field_errors }} in the
-template. If used on its own, it is displayed as a
(or an empty string, if
-the list of errors is empty). You can also use it in {% if %} statements.
->>> t = Template('''
''')
->>> print t.render(Context({'form': UserRegistration({'username': 'django', 'password1': 'foo', 'password2': 'bar'}, auto_id=False)}))
-
->>> t = Template('''''')
->>> print t.render(Context({'form': UserRegistration({'username': 'django', 'password1': 'foo', 'password2': 'bar'}, auto_id=False)}))
-
-
-###############
-# Extra stuff #
-###############
-
-The newforms library comes with some extra, higher-level Field and Widget
-classes that demonstrate some of the library's abilities.
-
-# SelectDateWidget ############################################################
-
->>> from django.newforms.extras import SelectDateWidget
->>> w = SelectDateWidget(years=('2007','2008','2009','2010','2011','2012','2013','2014','2015','2016'))
->>> print w.render('mydate', '')
-
-
-
->>> w.render('mydate', None) == w.render('mydate', '')
-True
->>> print w.render('mydate', '2010-04-15')
-
-
-
-
-Using a SelectDateWidget in a form:
-
->>> class GetDate(Form):
-... mydate = DateField(widget=SelectDateWidget)
->>> a = GetDate({'mydate_month':'4', 'mydate_day':'1', 'mydate_year':'2008'})
->>> print a.is_valid()
-True
->>> print a.cleaned_data['mydate']
-2008-04-01
-
-As with any widget that implements get_value_from_datadict,
-we must be prepared to accept the input from the "as_hidden"
-rendering as well.
-
->>> print a['mydate'].as_hidden()
-
->>> b=GetDate({'mydate':'2008-4-1'})
->>> print b.is_valid()
-True
->>> print b.cleaned_data['mydate']
-2008-04-01
-
-
-# MultiWidget and MultiValueField #############################################
-# MultiWidgets are widgets composed of other widgets. They are usually
-# combined with MultiValueFields - a field that is composed of other fields.
-# MulitWidgets can themselved be composed of other MultiWidgets.
-# SplitDateTimeWidget is one example of a MultiWidget.
-
->>> class ComplexMultiWidget(MultiWidget):
-... def __init__(self, attrs=None):
-... widgets = (
-... TextInput(),
-... SelectMultiple(choices=(('J', 'John'), ('P', 'Paul'), ('G', 'George'), ('R', 'Ringo'))),
-... SplitDateTimeWidget(),
-... )
-... super(ComplexMultiWidget, self).__init__(widgets, attrs)
-...
-... def decompress(self, value):
-... if value:
-... data = value.split(',')
-... return [data[0], data[1], datetime.datetime(*time.strptime(data[2], "%Y-%m-%d %H:%M:%S")[0:6])]
-... return [None, None, None]
-... def format_output(self, rendered_widgets):
-... return u'\n'.join(rendered_widgets)
->>> w = ComplexMultiWidget()
->>> print w.render('name', 'some text,JP,2007-04-25 06:24:00')
-
-
-
-
->>> class ComplexField(MultiValueField):
-... def __init__(self, required=True, widget=None, label=None, initial=None):
-... fields = (
-... CharField(),
-... MultipleChoiceField(choices=(('J', 'John'), ('P', 'Paul'), ('G', 'George'), ('R', 'Ringo'))),
-... SplitDateTimeField()
-... )
-... super(ComplexField, self).__init__(fields, required, widget, label, initial)
-...
-... def compress(self, data_list):
-... if data_list:
-... return '%s,%s,%s' % (data_list[0],''.join(data_list[1]),data_list[2])
-... return None
-
->>> f = ComplexField(widget=w)
->>> f.clean(['some text', ['J','P'], ['2007-04-25','6:24:00']])
-u'some text,JP,2007-04-25 06:24:00'
->>> f.clean(['some text',['X'], ['2007-04-25','6:24:00']])
-Traceback (most recent call last):
-...
-ValidationError: [u'Select a valid choice. X is not one of the available choices.']
-
-# If insufficient data is provided, None is substituted
->>> f.clean(['some text',['JP']])
-Traceback (most recent call last):
-...
-ValidationError: [u'This field is required.']
-
->>> class ComplexFieldForm(Form):
-... field1 = ComplexField(widget=w)
->>> f = ComplexFieldForm()
->>> print f
-
Field1:
-
-
-
->>> f = ComplexFieldForm({'field1_0':'some text','field1_1':['J','P'], 'field1_2_0':'2007-04-25', 'field1_2_1':'06:24:00'})
->>> print f
-
Field1:
-
-
-
->>> f.cleaned_data
-{'field1': u'some text,JP,2007-04-25 06:24:00'}
-
-#################################
-# Tests of underlying functions #
-#################################
-
-# smart_unicode tests
->>> from django.utils.encoding import smart_unicode
->>> class Test:
-... def __str__(self):
-... return 'ŠĐĆŽćžšđ'
->>> class TestU:
-... def __str__(self):
-... return 'Foo'
-... def __unicode__(self):
-... return u'\u0160\u0110\u0106\u017d\u0107\u017e\u0161\u0111'
->>> smart_unicode(Test())
-u'\u0160\u0110\u0106\u017d\u0107\u017e\u0161\u0111'
->>> smart_unicode(TestU())
-u'\u0160\u0110\u0106\u017d\u0107\u017e\u0161\u0111'
->>> smart_unicode(1)
-u'1'
->>> smart_unicode('foo')
-u'foo'
-
-
-####################################
-# Test accessing errors in clean() #
-####################################
-
->>> class UserForm(Form):
-... username = CharField(max_length=10)
-... password = CharField(widget=PasswordInput)
-... def clean(self):
-... data = self.cleaned_data
-... if not self.errors:
-... data['username'] = data['username'].lower()
-... return data
-
->>> f = UserForm({'username': 'SirRobin', 'password': 'blue'})
->>> f.is_valid()
-True
->>> f.cleaned_data['username']
-u'sirrobin'
-
-#######################################
-# Test overriding ErrorList in a form #
-#######################################
-
->>> from django.newforms.util import ErrorList
->>> class DivErrorList(ErrorList):
-... def __unicode__(self):
-... return self.as_divs()
-... def as_divs(self):
-... if not self: return u''
-... return u'
%s
' % ''.join([u'
%s
' % e for e in self])
->>> class CommentForm(Form):
-... name = CharField(max_length=50, required=False)
-... email = EmailField()
-... comment = CharField()
->>> data = dict(email='invalid')
->>> f = CommentForm(data, auto_id=False, error_class=DivErrorList)
->>> print f.as_p()
-
Name:
-
Enter a valid e-mail address.
-
Email:
-
This field is required.
-
Comment:
-
-#################################
-# Test multipart-encoded form #
-#################################
-
->>> class FormWithoutFile(Form):
-... username = CharField()
->>> class FormWithFile(Form):
-... username = CharField()
-... file = FileField()
->>> class FormWithImage(Form):
-... image = ImageField()
-
->>> FormWithoutFile().is_multipart()
-False
->>> FormWithFile().is_multipart()
-True
->>> FormWithImage().is_multipart()
-True
-
-"""
+from extra import tests as extra_tests
+from fields import tests as fields_tests
+from forms import tests as form_tests
+from localflavor.ar import tests as localflavor_ar_tests
+from localflavor.au import tests as localflavor_au_tests
+from localflavor.br import tests as localflavor_br_tests
+from localflavor.ca import tests as localflavor_ca_tests
+from localflavor.ch import tests as localflavor_ch_tests
+from localflavor.cl import tests as localflavor_cl_tests
+from localflavor.de import tests as localflavor_de_tests
+from localflavor.fi import tests as localflavor_fi_tests
+from localflavor.fr import tests as localflavor_fr_tests
+from localflavor.generic import tests as localflavor_generic_tests
+from localflavor.is_ import tests as localflavor_is_tests
+from localflavor.it import tests as localflavor_it_tests
+from localflavor.jp import tests as localflavor_jp_tests
+from localflavor.nl import tests as localflavor_nl_tests
+from localflavor.pl import tests as localflavor_pl_tests
+from localflavor.sk import tests as localflavor_sk_tests
+from localflavor.uk import tests as localflavor_uk_tests
+from localflavor.us import tests as localflavor_us_tests
+from regressions import tests as regression_tests
+from util import tests as util_tests
+from widgets import tests as widgets_tests
__test__ = {
+ 'extra_tests': extra_tests,
+ 'fields_tests': fields_tests,
'form_tests': form_tests,
- 'localflavor': localflavor_tests,
- 'regressions': regression_tests,
+ 'localflavor_ar_tests': localflavor_ar_tests,
+ 'localflavor_au_tests': localflavor_au_tests,
+ 'localflavor_br_tests': localflavor_br_tests,
+ 'localflavor_ca_tests': localflavor_ca_tests,
+ 'localflavor_ch_tests': localflavor_ch_tests,
+ 'localflavor_cl_tests': localflavor_cl_tests,
+ 'localflavor_de_tests': localflavor_de_tests,
+ 'localflavor_fi_tests': localflavor_fi_tests,
+ 'localflavor_fr_tests': localflavor_fr_tests,
+ 'localflavor_generic_tests': localflavor_generic_tests,
+ 'localflavor_is_tests': localflavor_is_tests,
+ 'localflavor_it_tests': localflavor_it_tests,
+ 'localflavor_jp_tests': localflavor_jp_tests,
+ 'localflavor_nl_tests': localflavor_nl_tests,
+ 'localflavor_pl_tests': localflavor_pl_tests,
+ 'localflavor_sk_tests': localflavor_sk_tests,
+ 'localflavor_uk_tests': localflavor_uk_tests,
+ 'localflavor_us_tests': localflavor_us_tests,
+ 'regressions_tests': regression_tests,
'util_tests': util_tests,
+ 'widgets_tests': widgets_tests,
}
if __name__ == "__main__":
--
cgit v1.3