# -*- coding: utf-8 -*- from __future__ import unicode_literals import datetime from django.core.files.uploadedfile import SimpleUploadedFile from django.forms import * from django.http import QueryDict from django.template import Template, Context from django.test import TestCase from django.test.utils import str_prefix from django.utils.datastructures import MultiValueDict, MergeDict from django.utils.safestring import mark_safe class Person(Form): first_name = CharField() last_name = CharField() birthday = DateField() class PersonNew(Form): first_name = CharField(widget=TextInput(attrs={'id': 'first_name_id'})) last_name = CharField() birthday = DateField() class FormsTestCase(TestCase): # 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. def test_form(self): # Pass a dictionary to a Form's __init__(). p = Person({'first_name': 'John', 'last_name': 'Lennon', 'birthday': '1940-10-9'}) self.assertTrue(p.is_bound) self.assertEqual(p.errors, {}) self.assertTrue(p.is_valid()) self.assertHTMLEqual(p.errors.as_ul(), '') self.assertEqual(p.errors.as_text(), '') self.assertEqual(p.cleaned_data["first_name"], 'John') self.assertEqual(p.cleaned_data["last_name"], 'Lennon') self.assertEqual(p.cleaned_data["birthday"], datetime.date(1940, 10, 9)) self.assertHTMLEqual(str(p['first_name']), '') self.assertHTMLEqual(str(p['last_name']), '') self.assertHTMLEqual(str(p['birthday']), '') try: p['nonexistentfield'] self.fail('Attempts to access non-existent fields should fail.') except KeyError: pass form_output = [] for boundfield in p: form_output.append(str(boundfield)) self.assertHTMLEqual('\n'.join(form_output), """ """) form_output = [] for boundfield in p: form_output.append([boundfield.label, boundfield.data]) self.assertEqual(form_output, [ ['First name', 'John'], ['Last name', 'Lennon'], ['Birthday', '1940-10-9'] ]) self.assertHTMLEqual(str(p), """ """) def test_empty_dict(self): # Empty dictionaries are valid, too. p = Person({}) self.assertTrue(p.is_bound) self.assertEqual(p.errors['first_name'], ['This field is required.']) self.assertEqual(p.errors['last_name'], ['This field is required.']) self.assertEqual(p.errors['birthday'], ['This field is required.']) self.assertFalse(p.is_valid()) self.assertEqual(p.cleaned_data, {}) self.assertHTMLEqual(str(p), """ """) self.assertHTMLEqual(p.as_table(), """ """) self.assertHTMLEqual(p.as_ul(), """
  • """) self.assertHTMLEqual(p.as_p(), """

    """) def test_unbound_form(self): # 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() self.assertFalse(p.is_bound) self.assertEqual(p.errors, {}) self.assertFalse(p.is_valid()) try: p.cleaned_data self.fail('Attempts to access cleaned_data when validation fails should fail.') except AttributeError: pass self.assertHTMLEqual(str(p), """ """) self.assertHTMLEqual(p.as_table(), """ """) self.assertHTMLEqual(p.as_ul(), """
  • """) self.assertHTMLEqual(p.as_p(), """

    """) def test_unicode_values(self): # Unicode values are handled properly. p = Person({'first_name': 'John', 'last_name': '\u0160\u0110\u0106\u017d\u0107\u017e\u0161\u0111', 'birthday': '1940-10-9'}) self.assertHTMLEqual(p.as_table(), '\n\n') self.assertHTMLEqual(p.as_ul(), '
  • \n
  • \n
  • ') self.assertHTMLEqual(p.as_p(), '

    \n

    \n

    ') p = Person({'last_name': 'Lennon'}) self.assertEqual(p.errors['first_name'], ['This field is required.']) self.assertEqual(p.errors['birthday'], ['This field is required.']) self.assertFalse(p.is_valid()) self.assertHTMLEqual(p.errors.as_ul(), '') self.assertEqual(p.errors.as_text(), """* first_name * This field is required. * birthday * This field is required.""") self.assertEqual(p.cleaned_data, {'last_name': 'Lennon'}) self.assertEqual(p['first_name'].errors, ['This field is required.']) self.assertHTMLEqual(p['first_name'].errors.as_ul(), '') self.assertEqual(p['first_name'].errors.as_text(), '* This field is required.') p = Person() self.assertHTMLEqual(str(p['first_name']), '') self.assertHTMLEqual(str(p['last_name']), '') self.assertHTMLEqual(str(p['birthday']), '') def test_cleaned_data_only_fields(self): # 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': 'John', 'last_name': 'Lennon', 'birthday': '1940-10-9', 'extra1': 'hello', 'extra2': 'hello'} p = Person(data) self.assertTrue(p.is_valid()) self.assertEqual(p.cleaned_data['first_name'], 'John') self.assertEqual(p.cleaned_data['last_name'], 'Lennon') self.assertEqual(p.cleaned_data['birthday'], datetime.date(1940, 10, 9)) def test_optional_data(self): # 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': 'John', 'last_name': 'Lennon'} f = OptionalPersonForm(data) self.assertTrue(f.is_valid()) self.assertEqual(f.cleaned_data['nick_name'], '') self.assertEqual(f.cleaned_data['first_name'], 'John') self.assertEqual(f.cleaned_data['last_name'], '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': 'John', 'last_name': 'Lennon'} f = OptionalPersonForm(data) self.assertTrue(f.is_valid()) self.assertEqual(f.cleaned_data['birth_date'], None) self.assertEqual(f.cleaned_data['first_name'], 'John') self.assertEqual(f.cleaned_data['last_name'], 'Lennon') def test_auto_id(self): # "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