1 from datetime
import date
4 from django
import forms
5 from django
.forms
.models
import modelform_factory
, ModelChoiceField
6 from django
.conf
import settings
7 from django
.test
import TestCase
9 from models
import Person
, RealPerson
, Triple
, FilePathModel
, Article
, Publication
, CustomFF
, Author
, Author1
12 class ModelMultipleChoiceFieldTests(TestCase
):
15 self
.old_debug
= settings
.DEBUG
19 settings
.DEBUG
= self
.old_debug
21 def test_model_multiple_choice_number_of_queries(self
):
23 Test that ModelMultipleChoiceField does O(1) queries instead of
27 Person
.objects
.create(name
="Person %s" % i
)
30 f
= forms
.ModelMultipleChoiceField(queryset
=Person
.objects
.all())
31 selected
= f
.clean([1, 3, 5, 7, 9])
32 self
.assertEquals(len(db
.connection
.queries
), 1)
34 class TripleForm(forms
.ModelForm
):
38 class UniqueTogetherTests(TestCase
):
39 def test_multiple_field_unique_together(self
):
41 When the same field is involved in multiple unique_together
42 constraints, we need to make sure we don't remove the data for it
43 before doing all the validation checking (not just failing after
46 Triple
.objects
.create(left
=1, middle
=2, right
=3)
48 form
= TripleForm({'left': '1', 'middle': '2', 'right': '3'})
49 self
.failIf(form
.is_valid())
51 form
= TripleForm({'left': '1', 'middle': '3', 'right': '1'})
52 self
.failUnless(form
.is_valid())
54 class TripleFormWithCleanOverride(forms
.ModelForm
):
59 if not self
.cleaned_data
['left'] == self
.cleaned_data
['right']:
60 raise forms
.ValidationError('Left and right should be equal')
61 return self
.cleaned_data
63 class OverrideCleanTests(TestCase
):
64 def test_override_clean(self
):
66 Regression for #12596: Calling super from ModelForm.clean() should be
69 form
= TripleFormWithCleanOverride({'left': 1, 'middle': 2, 'right': 1})
70 self
.failUnless(form
.is_valid())
71 # form.instance.left will be None if the instance was not constructed
72 # by form.full_clean().
73 self
.assertEquals(form
.instance
.left
, 1)
75 # Regression test for #12960.
76 # Make sure the cleaned_data returned from ModelForm.clean() is applied to the
79 class PublicationForm(forms
.ModelForm
):
81 self
.cleaned_data
['title'] = self
.cleaned_data
['title'].upper()
82 return self
.cleaned_data
87 class ModelFormCleanTest(TestCase
):
88 def test_model_form_clean_applies_to_model(self
):
89 data
= {'title': 'test', 'date_published': '2010-2-25'}
90 form
= PublicationForm(data
)
91 publication
= form
.save()
92 self
.assertEqual(publication
.title
, 'TEST')
94 class FPForm(forms
.ModelForm
):
98 class FilePathFieldTests(TestCase
):
99 def test_file_path_field_blank(self
):
101 Regression test for #8842: FilePathField(blank=True)
104 names
= [p
[1] for p
in form
['path'].field
.choices
]
106 self
.assertEqual(names
, ['---------', '__init__.py', 'models.py', 'tests.py'])
108 class ManyToManyCallableInitialTests(TestCase
):
109 def test_callable(self
):
110 "Regression for #10349: A callable can be provided as the initial value for an m2m field"
112 # Set up a callable initial value
113 def formfield_for_dbfield(db_field
, **kwargs
):
114 if db_field
.name
== 'publications':
115 kwargs
['initial'] = lambda: Publication
.objects
.all().order_by('date_published')[:2]
116 return db_field
.formfield(**kwargs
)
118 # Set up some Publications to use as data
119 Publication(title
="First Book", date_published
=date(2007,1,1)).save()
120 Publication(title
="Second Book", date_published
=date(2008,1,1)).save()
121 Publication(title
="Third Book", date_published
=date(2009,1,1)).save()
123 # Create a ModelForm, instantiate it, and check that the output is as expected
124 ModelForm
= modelform_factory(Article
, formfield_callback
=formfield_for_dbfield
)
126 self
.assertEquals(form
.as_ul(), u
"""<li><label for="id_headline">Headline:</label> <input id="id_headline" type="text" name="headline" maxlength="100" /></li>
127 <li><label for="id_publications">Publications:</label> <select multiple="multiple" name="publications" id="id_publications">
128 <option value="1" selected="selected">First Book</option>
129 <option value="2" selected="selected">Second Book</option>
130 <option value="3">Third Book</option>
131 </select> Hold down "Control", or "Command" on a Mac, to select more than one.</li>""")
133 class CFFForm(forms
.ModelForm
):
137 class CustomFieldSaveTests(TestCase
):
139 "Regression for #11149: save_form_data should be called only once"
141 # It's enough that the form saves without error -- the custom save routine will
142 # generate an AssertionError if it is called more than once during save.
143 form
= CFFForm(data
= {'f': None})
146 class ModelChoiceIteratorTests(TestCase
):
148 class Form(forms
.ModelForm
):
151 fields
= ["publications"]
153 Publication
.objects
.create(title
="Pravda",
154 date_published
=date(1991, 8, 22))
156 self
.assertEqual(len(f
.fields
["publications"].choices
), 1)
158 class RealPersonForm(forms
.ModelForm
):
162 class CustomModelFormSaveMethod(TestCase
):
163 def test_string_message(self
):
164 data
= {'name': 'anonymous'}
165 form
= RealPersonForm(data
)
166 self
.assertEqual(form
.is_valid(), False)
167 self
.assertEqual(form
.errors
['__all__'], ['Please specify a real name.'])
169 class ModelClassTests(TestCase
):
170 def test_no_model_class(self
):
171 class NoModelModelForm(forms
.ModelForm
):
173 self
.assertRaises(ValueError, NoModelModelForm
)
175 class OneToOneFieldTests(TestCase
):
176 def test_assignment_of_none(self
):
177 class AuthorForm(forms
.ModelForm
):
180 fields
= ['publication', 'full_name']
182 publication
= Publication
.objects
.create(title
="Pravda",
183 date_published
=date(1991, 8, 22))
184 author
= Author
.objects
.create(publication
=publication
, full_name
='John Doe')
185 form
= AuthorForm({'publication':u
'', 'full_name':'John Doe'}, instance
=author
)
186 self
.assert_(form
.is_valid())
187 self
.assertEqual(form
.cleaned_data
['publication'], None)
189 # author object returned from form still retains original publication object
190 # that's why we need to retreive it from database again
191 new_author
= Author
.objects
.get(pk
=author
.pk
)
192 self
.assertEqual(new_author
.publication
, None)
194 def test_assignment_of_none_null_false(self
):
195 class AuthorForm(forms
.ModelForm
):
198 fields
= ['publication', 'full_name']
200 publication
= Publication
.objects
.create(title
="Pravda",
201 date_published
=date(1991, 8, 22))
202 author
= Author1
.objects
.create(publication
=publication
, full_name
='John Doe')
203 form
= AuthorForm({'publication':u
'', 'full_name':'John Doe'}, instance
=author
)
204 self
.assert_(not form
.is_valid())
207 class ModelChoiceForm(forms
.Form
):
208 person
= ModelChoiceField(Person
.objects
.all())
211 class TestTicket11183(TestCase
):
212 def test_11183(self
):
213 form1
= ModelChoiceForm()
214 field1
= form1
.fields
['person']
215 # To allow the widget to change the queryset of field1.widget.choices correctly,
216 # without affecting other forms, the following must hold:
217 self
.assert_(field1
is not ModelChoiceForm
.base_fields
['person'])
218 self
.assert_(field1
.widget
.choices
.field
is field1
)