diff options
| author | Andrew Godwin <andrew@aeracode.org> | 2013-06-19 12:03:20 +0100 |
|---|---|---|
| committer | Andrew Godwin <andrew@aeracode.org> | 2013-06-19 12:05:23 +0100 |
| commit | 9daf81b94e7945d7adfdf62206cf9cb436166f0d (patch) | |
| tree | 0ca2a77977432d0c139886297afb433569b588ca /tests/model_forms | |
| parent | 315ab41e416c777d4f42932d42df07872e8f8895 (diff) | |
| parent | d9a43545be1af95a13c181c8b178f5631d3a4148 (diff) | |
Merge remote-tracking branch 'core/master' into schema-alteration
Conflicts:
django/db/models/loading.py
Diffstat (limited to 'tests/model_forms')
| -rw-r--r-- | tests/model_forms/models.py | 37 | ||||
| -rw-r--r-- | tests/model_forms/tests.py | 179 |
2 files changed, 154 insertions, 62 deletions
diff --git a/tests/model_forms/models.py b/tests/model_forms/models.py index 610dc34001..a4cf9471de 100644 --- a/tests/model_forms/models.py +++ b/tests/model_forms/models.py @@ -11,13 +11,13 @@ from __future__ import unicode_literals import os import tempfile +from django.core import validators from django.core.exceptions import ImproperlyConfigured from django.core.files.storage import FileSystemStorage from django.db import models from django.utils import six from django.utils.encoding import python_2_unicode_compatible -from shared_models.models import Author, Book temp_storage_dir = tempfile.mkdtemp(dir=os.environ['DJANGO_TEST_TEMP_DIR']) temp_storage = FileSystemStorage(temp_storage_dir) @@ -47,12 +47,22 @@ class Category(models.Model): return self.__str__() @python_2_unicode_compatible +class Writer(models.Model): + name = models.CharField(max_length=50, help_text='Use both first and last names.') + + class Meta: + ordering = ('name',) + + def __str__(self): + return self.name + +@python_2_unicode_compatible class Article(models.Model): headline = models.CharField(max_length=50) slug = models.SlugField() pub_date = models.DateField() created = models.DateField(editable=False) - writer = models.ForeignKey(Author) + writer = models.ForeignKey(Writer) article = models.TextField() categories = models.ManyToManyField(Category, blank=True) status = models.PositiveIntegerField(choices=ARTICLE_STATUS, blank=True, null=True) @@ -72,12 +82,12 @@ class ImprovedArticle(models.Model): class ImprovedArticleWithParentLink(models.Model): article = models.OneToOneField(Article, parent_link=True) -class BetterAuthor(Author): +class BetterWriter(Writer): score = models.IntegerField() @python_2_unicode_compatible -class AuthorProfile(models.Model): - writer = models.OneToOneField(Author, primary_key=True) +class WriterProfile(models.Model): + writer = models.OneToOneField(Writer, primary_key=True) age = models.PositiveIntegerField() def __str__(self): @@ -177,6 +187,14 @@ class Inventory(models.Model): def __repr__(self): return self.__str__() +class Book(models.Model): + title = models.CharField(max_length=40) + author = models.ForeignKey(Writer, blank=True, null=True) + special_id = models.IntegerField(blank=True, null=True, unique=True) + + class Meta: + unique_together = ('title', 'author') + class BookXtra(models.Model): isbn = models.CharField(max_length=16, unique=True) suffix1 = models.IntegerField(blank=True, default=0) @@ -269,3 +287,12 @@ class ColourfulItem(models.Model): class ArticleStatusNote(models.Model): name = models.CharField(max_length=20) status = models.ManyToManyField(ArticleStatus) + +class CustomErrorMessage(models.Model): + name1 = models.CharField(max_length=50, + validators=[validators.validate_slug], + error_messages={'invalid': 'Model custom error message.'}) + + name2 = models.CharField(max_length=50, + validators=[validators.validate_slug], + error_messages={'invalid': 'Model custom error message.'}) diff --git a/tests/model_forms/tests.py b/tests/model_forms/tests.py index 58dde13a8a..39be824798 100644 --- a/tests/model_forms/tests.py +++ b/tests/model_forms/tests.py @@ -17,14 +17,12 @@ from django.utils.unittest import skipUnless from django.test import TestCase from django.utils import six -from shared_models.models import Author, Book - -from .models import (Article, ArticleStatus, BetterAuthor, BigInt, +from .models import (Article, ArticleStatus, BetterWriter, BigInt, Book, Category, CommaSeparatedInteger, CustomFieldForExclusionModel, DerivedBook, DerivedPost, ExplicitPK, FlexibleDatePost, ImprovedArticle, ImprovedArticleWithParentLink, Inventory, Post, Price, - Product, TextFile, AuthorProfile, Colour, ColourfulItem, - ArticleStatusNote, DateTimePost, test_images) + Product, TextFile, Writer, WriterProfile, Colour, ColourfulItem, + ArticleStatusNote, DateTimePost, CustomErrorMessage, test_images) if test_images: from .models import ImageFile, OptionalImageFile @@ -54,14 +52,15 @@ class PriceForm(forms.ModelForm): class BookForm(forms.ModelForm): class Meta: - fields = ['title', 'author', 'pubdate'] model = Book + fields = '__all__' class DerivedBookForm(forms.ModelForm): class Meta: - fields = ['title', 'author', 'isbn', 'suffix1', 'suffix2'] model = DerivedBook + fields = '__all__' + class ExplicitPKForm(forms.ModelForm): @@ -88,11 +87,11 @@ class DerivedPostForm(forms.ModelForm): fields = '__all__' -class CustomAuthorForm(forms.ModelForm): +class CustomWriterForm(forms.ModelForm): name = forms.CharField(required=False) class Meta: - model = Author + model = Writer fields = '__all__' @@ -128,7 +127,7 @@ class PartialArticleForm(forms.ModelForm): class RoykoForm(forms.ModelForm): class Meta: - model = Author + model = Writer fields = '__all__' @@ -188,15 +187,14 @@ class ImprovedArticleWithParentLinkForm(forms.ModelForm): fields = '__all__' -class BetterAuthorForm(forms.ModelForm): +class BetterWriterForm(forms.ModelForm): class Meta: - model = BetterAuthor + model = BetterWriter fields = '__all__' - -class AuthorProfileForm(forms.ModelForm): +class WriterProfileForm(forms.ModelForm): class Meta: - model = AuthorProfile + model = WriterProfile fields = '__all__' @@ -254,6 +252,12 @@ class StatusNoteCBM2mForm(forms.ModelForm): fields = '__all__' widgets = {'status': forms.CheckboxSelectMultiple} +class CustomErrorMessageForm(forms.ModelForm): + name1 = forms.CharField(error_messages={'invalid': 'Form custom error message.'}) + + class Meta: + model = CustomErrorMessage + class ModelFormBaseTest(TestCase): def test_base_form(self): @@ -324,14 +328,14 @@ class ModelFormBaseTest(TestCase): forms.fields.BooleanField) def test_override_field(self): - class AuthorForm(forms.ModelForm): + class WriterForm(forms.ModelForm): book = forms.CharField(required=False) class Meta: - model = Author + model = Writer fields = '__all__' - wf = AuthorForm({'name': 'Richard Lockridge'}) + wf = WriterForm({'name': 'Richard Lockridge'}) self.assertTrue(wf.is_valid()) def test_limit_nonexistent_field(self): @@ -495,7 +499,7 @@ class ModelFormBaseTest(TestCase): ['slug', 'name']) -class TestWidgetForm(forms.ModelForm): +class FieldOverridesTroughFormMetaForm(forms.ModelForm): class Meta: model = Category fields = ['name', 'url', 'slug'] @@ -503,25 +507,74 @@ class TestWidgetForm(forms.ModelForm): 'name': forms.Textarea, 'url': forms.TextInput(attrs={'class': 'url'}) } + labels = { + 'name': 'Title', + } + help_texts = { + 'slug': 'Watch out! Letters, numbers, underscores and hyphens only.', + } + error_messages = { + 'slug': { + 'invalid': ( + "Didn't you read the help text? " + "We said letters, numbers, underscores and hyphens only!" + ) + } + } +class TestFieldOverridesTroughFormMeta(TestCase): + def test_widget_overrides(self): + form = FieldOverridesTroughFormMetaForm() + self.assertHTMLEqual( + str(form['name']), + '<textarea id="id_name" rows="10" cols="40" name="name"></textarea>', + ) + self.assertHTMLEqual( + str(form['url']), + '<input id="id_url" type="text" class="url" name="url" maxlength="40" />', + ) + self.assertHTMLEqual( + str(form['slug']), + '<input id="id_slug" type="text" name="slug" maxlength="20" />', + ) -class TestWidgets(TestCase): - def test_base_widgets(self): - frm = TestWidgetForm() + def test_label_overrides(self): + form = FieldOverridesTroughFormMetaForm() self.assertHTMLEqual( - str(frm['name']), - '<textarea id="id_name" rows="10" cols="40" name="name"></textarea>' + str(form['name'].label_tag()), + '<label for="id_name">Title:</label>', ) self.assertHTMLEqual( - str(frm['url']), - '<input id="id_url" type="text" class="url" name="url" maxlength="40" />' + str(form['url'].label_tag()), + '<label for="id_url">The URL:</label>', ) self.assertHTMLEqual( - str(frm['slug']), - '<input id="id_slug" type="text" name="slug" maxlength="20" />' + str(form['slug'].label_tag()), + '<label for="id_slug">Slug:</label>', + ) + + def test_help_text_overrides(self): + form = FieldOverridesTroughFormMetaForm() + self.assertEqual( + form['slug'].help_text, + 'Watch out! Letters, numbers, underscores and hyphens only.', ) + def test_error_messages_overrides(self): + form = FieldOverridesTroughFormMetaForm(data={ + 'name': 'Category', + 'url': '/category/', + 'slug': '!%#*@', + }) + form.full_clean() + + error = [ + "Didn't you read the help text? " + "We said letters, numbers, underscores and hyphens only!", + ] + self.assertEqual(form.errors, {'slug': error}) + class IncompleteCategoryFormWithFields(forms.ModelForm): """ @@ -556,7 +609,7 @@ class ValidationTest(TestCase): assert form.is_valid() def test_notrequired_overrides_notblank(self): - form = CustomAuthorForm({}) + form = CustomWriterForm({}) assert form.is_valid() @@ -565,7 +618,7 @@ class ValidationTest(TestCase): # unique/unique_together validation class UniqueTest(TestCase): def setUp(self): - self.author = Author.objects.create(name='Mike Royko') + self.writer = Writer.objects.create(name='Mike Royko') def test_simple_unique(self): form = ProductForm({'slug': 'teddy-bear-blue'}) @@ -589,31 +642,33 @@ class UniqueTest(TestCase): def test_unique_null(self): title = 'I May Be Wrong But I Doubt It' - form = BookForm({'title': title, 'author': self.author.pk, 'pubdate': '2012-12-12 00:00:00'}) + form = BookForm({'title': title, 'author': self.writer.pk}) self.assertTrue(form.is_valid()) form.save() - form = BookForm({'title': title, 'author': self.author.pk, 'pubdate': '2012-12-12 00:00:00'}) + form = BookForm({'title': title, 'author': self.writer.pk}) self.assertFalse(form.is_valid()) self.assertEqual(len(form.errors), 1) self.assertEqual(form.errors['__all__'], ['Book with this Title and Author already exists.']) - form = BookForm({'title': title, 'pubdate': '2012-12-12 00:00:00'}) + form = BookForm({'title': title}) self.assertTrue(form.is_valid()) form.save() - form = BookForm({'title': title, 'pubdate': '2012-12-12 00:00:00'}) + form = BookForm({'title': title}) self.assertTrue(form.is_valid()) def test_inherited_unique(self): - form = BetterAuthorForm({'name': 'Mike Royko', 'score': 3}) + title = 'Boss' + Book.objects.create(title=title, author=self.writer, special_id=1) + form = DerivedBookForm({'title': 'Other', 'author': self.writer.pk, 'special_id': '1', 'isbn': '12345'}) self.assertFalse(form.is_valid()) self.assertEqual(len(form.errors), 1) - self.assertEqual(form.errors['name'], ['Author with this Name already exists.']) + self.assertEqual(form.errors['special_id'], ['Book with this Special id already exists.']) def test_inherited_unique_together(self): title = 'Boss' - form = BookForm({'title': title, 'author': self.author.pk, 'pubdate': '2012-12-12 00:00:00'}) + form = BookForm({'title': title, 'author': self.writer.pk}) self.assertTrue(form.is_valid()) form.save() - form = DerivedBookForm({'title': title, 'author': self.author.pk, 'isbn': '12345'}) + form = DerivedBookForm({'title': title, 'author': self.writer.pk, 'isbn': '12345'}) self.assertFalse(form.is_valid()) self.assertEqual(len(form.errors), 1) self.assertEqual(form.errors['__all__'], ['Book with this Title and Author already exists.']) @@ -621,9 +676,8 @@ class UniqueTest(TestCase): def test_abstract_inherited_unique(self): title = 'Boss' isbn = '12345' - dbook = DerivedBook.objects.create(title=title, author=self.author, isbn=isbn, - pubdate='2012-12-12 00:00') - form = DerivedBookForm({'title': 'Other', 'author': self.author.pk, 'isbn': isbn}) + dbook = DerivedBook.objects.create(title=title, author=self.writer, isbn=isbn) + form = DerivedBookForm({'title': 'Other', 'author': self.writer.pk, 'isbn': isbn}) self.assertFalse(form.is_valid()) self.assertEqual(len(form.errors), 1) self.assertEqual(form.errors['isbn'], ['Derived book with this Isbn already exists.']) @@ -631,11 +685,10 @@ class UniqueTest(TestCase): def test_abstract_inherited_unique_together(self): title = 'Boss' isbn = '12345' - dbook = DerivedBook.objects.create(title=title, author=self.author, isbn=isbn, - pubdate='2012-12-12 00:00') + dbook = DerivedBook.objects.create(title=title, author=self.writer, isbn=isbn) form = DerivedBookForm({ 'title': 'Other', - 'author': self.author.pk, + 'author': self.writer.pk, 'isbn': '9876', 'suffix1': '0', 'suffix2': '0' @@ -753,7 +806,7 @@ class ModelToDictTests(TestCase): ] for c in categories: c.save() - writer = Author(name='Test writer') + writer = Writer(name='Test writer') writer.save() art = Article( @@ -862,10 +915,10 @@ class OldFormForXTests(TestCase): with self.assertRaises(ValueError): f.save() - # Create a couple of Authors. - w_royko = Author(name='Mike Royko') + # Create a couple of Writers. + w_royko = Writer(name='Mike Royko') w_royko.save() - w_woodward = Author(name='Bob Woodward') + w_woodward = Writer(name='Bob Woodward') w_woodward.save() # ManyToManyFields are represented by a MultipleChoiceField, ForeignKeys and any # fields with the 'choices' attribute are represented by a ChoiceField. @@ -903,9 +956,9 @@ class OldFormForXTests(TestCase): # When the ModelForm is passed an instance, that instance's current values are # inserted as 'initial' data in each Field. - w = Author.objects.get(name='Mike Royko') + w = Writer.objects.get(name='Mike Royko') f = RoykoForm(auto_id=False, instance=w) - self.assertHTMLEqual(six.text_type(f), '''<tr><th>Name:</th><td><input type="text" name="name" value="Mike Royko" maxlength="100" /><br /><span class="helptext">Use both first and last names.</span></td></tr>''') + self.assertHTMLEqual(six.text_type(f), '''<tr><th>Name:</th><td><input type="text" name="name" value="Mike Royko" maxlength="50" /><br /><span class="helptext">Use both first and last names.</span></td></tr>''') art = Article( headline='Test article', @@ -1117,7 +1170,7 @@ class OldFormForXTests(TestCase): c4 = Category.objects.create(name='Fourth', url='4th') self.assertEqual(c4.name, 'Fourth') - w_bernstein = Author.objects.create(name='Carl Bernstein') + w_bernstein = Writer.objects.create(name='Carl Bernstein') self.assertEqual(w_bernstein.name, 'Carl Bernstein') self.assertHTMLEqual(f.as_ul(), '''<li>Headline: <input type="text" name="headline" maxlength="50" /></li> <li>Slug: <input type="text" name="slug" maxlength="50" /></li> @@ -1294,17 +1347,17 @@ class OldFormForXTests(TestCase): self.assertEqual(list(ImprovedArticleWithParentLinkForm.base_fields), []) - bw = BetterAuthor(name='Joe Better', score=10) + bw = BetterWriter(name='Joe Better', score=10) bw.save() self.assertEqual(sorted(model_to_dict(bw)), - ['author_ptr', 'id', 'name', 'score']) + ['id', 'name', 'score', 'writer_ptr']) - form = BetterAuthorForm({'name': 'Some Name', 'score': 12}) + form = BetterWriterForm({'name': 'Some Name', 'score': 12}) self.assertEqual(form.is_valid(), True) bw2 = form.save() bw2.delete() - form = AuthorProfileForm() + form = WriterProfileForm() self.assertHTMLEqual(form.as_p(), '''<p><label for="id_writer">Writer:</label> <select name="writer" id="id_writer"> <option value="" selected="selected">---------</option> <option value="%s">Bob Woodward</option> @@ -1318,11 +1371,11 @@ class OldFormForXTests(TestCase): 'writer': six.text_type(w_woodward.pk), 'age': '65', } - form = AuthorProfileForm(data) + form = WriterProfileForm(data) instance = form.save() self.assertEqual(six.text_type(instance), 'Bob Woodward is 65') - form = AuthorProfileForm(instance=instance) + form = WriterProfileForm(instance=instance) self.assertHTMLEqual(form.as_p(), '''<p><label for="id_writer">Writer:</label> <select name="writer" id="id_writer"> <option value="">---------</option> <option value="%s" selected="selected">Bob Woodward</option> @@ -1715,6 +1768,18 @@ class OldFormForXTests(TestCase): </select> <span class="helptext"> Hold down "Control", or "Command" on a Mac, to select more than one.</span></p>""" % {'blue_pk': colour.pk}) + def test_custom_error_messages(self) : + data = {'name1': '@#$!!**@#$', 'name2': '@#$!!**@#$'} + errors = CustomErrorMessageForm(data).errors + self.assertHTMLEqual( + str(errors['name1']), + '<ul class="errorlist"><li>Form custom error message.</li></ul>' + ) + self.assertHTMLEqual( + str(errors['name2']), + '<ul class="errorlist"><li>Model custom error message.</li></ul>' + ) + class M2mHelpTextTest(TestCase): """Tests for ticket #9321.""" |
