Add Django-1.2.1
[frozenviper.git] / Django-1.2.1 / tests / regressiontests / model_forms_regress / tests.py
blob5a7a83bc0e3d159015947ecb82856387c685a934
1 from datetime import date
3 from django import db
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):
14 def setUp(self):
15 self.old_debug = settings.DEBUG
16 settings.DEBUG = True
18 def tearDown(self):
19 settings.DEBUG = self.old_debug
21 def test_model_multiple_choice_number_of_queries(self):
22 """
23 Test that ModelMultipleChoiceField does O(1) queries instead of
24 O(n) (#10156).
25 """
26 for i in range(30):
27 Person.objects.create(name="Person %s" % i)
29 db.reset_queries()
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):
35 class Meta:
36 model = Triple
38 class UniqueTogetherTests(TestCase):
39 def test_multiple_field_unique_together(self):
40 """
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
44 the first one).
45 """
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):
55 class Meta:
56 model = Triple
58 def clean(self):
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):
65 """
66 Regression for #12596: Calling super from ModelForm.clean() should be
67 optional.
68 """
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
77 # model instance.
79 class PublicationForm(forms.ModelForm):
80 def clean(self):
81 self.cleaned_data['title'] = self.cleaned_data['title'].upper()
82 return self.cleaned_data
84 class Meta:
85 model = Publication
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):
95 class Meta:
96 model = FilePathModel
98 class FilePathFieldTests(TestCase):
99 def test_file_path_field_blank(self):
101 Regression test for #8842: FilePathField(blank=True)
103 form = FPForm()
104 names = [p[1] for p in form['path'].field.choices]
105 names.sort()
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)
125 form = ModelForm()
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):
134 class Meta:
135 model = CustomFF
137 class CustomFieldSaveTests(TestCase):
138 def test_save(self):
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})
144 form.save()
146 class ModelChoiceIteratorTests(TestCase):
147 def test_len(self):
148 class Form(forms.ModelForm):
149 class Meta:
150 model = Article
151 fields = ["publications"]
153 Publication.objects.create(title="Pravda",
154 date_published=date(1991, 8, 22))
155 f = Form()
156 self.assertEqual(len(f.fields["publications"].choices), 1)
158 class RealPersonForm(forms.ModelForm):
159 class Meta:
160 model = RealPerson
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):
172 pass
173 self.assertRaises(ValueError, NoModelModelForm)
175 class OneToOneFieldTests(TestCase):
176 def test_assignment_of_none(self):
177 class AuthorForm(forms.ModelForm):
178 class Meta:
179 model = Author
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)
188 author = form.save()
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):
196 class Meta:
197 model = Author1
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)