mirror of
https://github.com/django/django.git
synced 2024-12-22 17:16:24 +00:00
Began implementing a shared set of test models to speed up tests.
This commit is contained in:
parent
1059da8de6
commit
22b7870e40
@ -5,6 +5,7 @@ from operator import attrgetter
|
||||
|
||||
from django.core.exceptions import FieldError
|
||||
from django.test import TestCase, skipUnlessDBFeature
|
||||
from django.utils import six
|
||||
|
||||
from shared_models.models import Author, Book
|
||||
|
||||
@ -20,19 +21,19 @@ class LookupTests(TestCase):
|
||||
self.au2 = Author(name='Author 2')
|
||||
self.au2.save()
|
||||
# Create a couple of Books.
|
||||
self.b1 = Book(name='Book 1', pubdate=datetime(2005, 7, 26), author=self.au1)
|
||||
self.b1 = Book(title='Book 1', pubdate=datetime(2005, 7, 26), author=self.au1)
|
||||
self.b1.save()
|
||||
self.b2 = Book(name='Book 2', pubdate=datetime(2005, 7, 27), author=self.au1)
|
||||
self.b2 = Book(title='Book 2', pubdate=datetime(2005, 7, 27), author=self.au1)
|
||||
self.b2.save()
|
||||
self.b3 = Book(name='Book 3', pubdate=datetime(2005, 7, 27), author=self.au1)
|
||||
self.b3 = Book(title='Book 3', pubdate=datetime(2005, 7, 27), author=self.au1)
|
||||
self.b3.save()
|
||||
self.b4 = Book(name='Book 4', pubdate=datetime(2005, 7, 28), author=self.au1)
|
||||
self.b4 = Book(title='Book 4', pubdate=datetime(2005, 7, 28), author=self.au1)
|
||||
self.b4.save()
|
||||
self.b5 = Book(name='Book 5', pubdate=datetime(2005, 8, 1, 9, 0), author=self.au2)
|
||||
self.b5 = Book(title='Book 5', pubdate=datetime(2005, 8, 1, 9, 0), author=self.au2)
|
||||
self.b5.save()
|
||||
self.b6 = Book(name='Book 6', pubdate=datetime(2005, 8, 1, 8, 0), author=self.au2)
|
||||
self.b6 = Book(title='Book 6', pubdate=datetime(2005, 8, 1, 8, 0), author=self.au2)
|
||||
self.b6.save()
|
||||
self.b7 = Book(name='Book 7', pubdate=datetime(2005, 7, 27), author=self.au2)
|
||||
self.b7 = Book(title='Book 7', pubdate=datetime(2005, 7, 27), author=self.au2)
|
||||
self.b7.save()
|
||||
# Create a few Tags.
|
||||
self.t1 = Tag(name='Tag 1')
|
||||
@ -85,18 +86,18 @@ class LookupTests(TestCase):
|
||||
'Book 7',
|
||||
'Book 1',
|
||||
],
|
||||
transform=attrgetter('name'))
|
||||
transform=attrgetter('title'))
|
||||
# iterator() can be used on any QuerySet.
|
||||
self.assertQuerysetEqual(
|
||||
Book.objects.filter(name__endswith='4').iterator(),
|
||||
Book.objects.filter(title__endswith='4').iterator(),
|
||||
['Book 4'],
|
||||
transform=attrgetter('name'))
|
||||
transform=attrgetter('title'))
|
||||
|
||||
def test_count(self):
|
||||
# count() returns the number of objects matching search criteria.
|
||||
self.assertEqual(Book.objects.count(), 7)
|
||||
self.assertEqual(Book.objects.filter(pubdate__exact=datetime(2005, 7, 27)).count(), 3)
|
||||
self.assertEqual(Book.objects.filter(name__startswith='Blah blah').count(), 0)
|
||||
self.assertEqual(Book.objects.filter(title__startswith='Blah blah').count(), 0)
|
||||
|
||||
# count() should respect sliced query sets.
|
||||
articles = Book.objects.all()
|
||||
@ -128,43 +129,43 @@ class LookupTests(TestCase):
|
||||
# values() returns a list of dictionaries instead of object instances --
|
||||
# and you can specify which fields you want to retrieve.
|
||||
identity = lambda x:x
|
||||
self.assertQuerysetEqual(Book.objects.values('name'),
|
||||
self.assertQuerysetEqual(Book.objects.values('title'),
|
||||
[
|
||||
{'name': 'Book 5'},
|
||||
{'name': 'Book 6'},
|
||||
{'name': 'Book 4'},
|
||||
{'name': 'Book 2'},
|
||||
{'name': 'Book 3'},
|
||||
{'name': 'Book 7'},
|
||||
{'name': 'Book 1'},
|
||||
{'title': 'Book 5'},
|
||||
{'title': 'Book 6'},
|
||||
{'title': 'Book 4'},
|
||||
{'title': 'Book 2'},
|
||||
{'title': 'Book 3'},
|
||||
{'title': 'Book 7'},
|
||||
{'title': 'Book 1'},
|
||||
],
|
||||
transform=identity)
|
||||
self.assertQuerysetEqual(
|
||||
Book.objects.filter(pubdate__exact=datetime(2005, 7, 27)).values('id'),
|
||||
[{'id': self.b2.id}, {'id': self.b3.id}, {'id': self.b7.id}],
|
||||
transform=identity)
|
||||
self.assertQuerysetEqual(Book.objects.values('id', 'name'),
|
||||
self.assertQuerysetEqual(Book.objects.values('id', 'title'),
|
||||
[
|
||||
{'id': self.b5.id, 'name': 'Book 5'},
|
||||
{'id': self.b6.id, 'name': 'Book 6'},
|
||||
{'id': self.b4.id, 'name': 'Book 4'},
|
||||
{'id': self.b2.id, 'name': 'Book 2'},
|
||||
{'id': self.b3.id, 'name': 'Book 3'},
|
||||
{'id': self.b7.id, 'name': 'Book 7'},
|
||||
{'id': self.b1.id, 'name': 'Book 1'},
|
||||
{'id': self.b5.id, 'title': 'Book 5'},
|
||||
{'id': self.b6.id, 'title': 'Book 6'},
|
||||
{'id': self.b4.id, 'title': 'Book 4'},
|
||||
{'id': self.b2.id, 'title': 'Book 2'},
|
||||
{'id': self.b3.id, 'title': 'Book 3'},
|
||||
{'id': self.b7.id, 'title': 'Book 7'},
|
||||
{'id': self.b1.id, 'title': 'Book 1'},
|
||||
],
|
||||
transform=identity)
|
||||
# You can use values() with iterator() for memory savings,
|
||||
# because iterator() uses database-level iteration.
|
||||
self.assertQuerysetEqual(Book.objects.values('id', 'name').iterator(),
|
||||
self.assertQuerysetEqual(Book.objects.values('id', 'title').iterator(),
|
||||
[
|
||||
{'name': 'Book 5', 'id': self.b5.id},
|
||||
{'name': 'Book 6', 'id': self.b6.id},
|
||||
{'name': 'Book 4', 'id': self.b4.id},
|
||||
{'name': 'Book 2', 'id': self.b2.id},
|
||||
{'name': 'Book 3', 'id': self.b3.id},
|
||||
{'name': 'Book 7', 'id': self.b7.id},
|
||||
{'name': 'Book 1', 'id': self.b1.id},
|
||||
{'title': 'Book 5', 'id': self.b5.id},
|
||||
{'title': 'Book 6', 'id': self.b6.id},
|
||||
{'title': 'Book 4', 'id': self.b4.id},
|
||||
{'title': 'Book 2', 'id': self.b2.id},
|
||||
{'title': 'Book 3', 'id': self.b3.id},
|
||||
{'title': 'Book 7', 'id': self.b7.id},
|
||||
{'title': 'Book 1', 'id': self.b1.id},
|
||||
],
|
||||
transform=identity)
|
||||
# The values() method works with "extra" fields specified in extra(select).
|
||||
@ -204,39 +205,39 @@ class LookupTests(TestCase):
|
||||
}], transform=identity)
|
||||
# You can specify fields from forward and reverse relations, just like filter().
|
||||
self.assertQuerysetEqual(
|
||||
Book.objects.values('name', 'author__name'),
|
||||
Book.objects.values('title', 'author__name'),
|
||||
[
|
||||
{'name': self.b5.name, 'author__name': self.au2.name},
|
||||
{'name': self.b6.name, 'author__name': self.au2.name},
|
||||
{'name': self.b4.name, 'author__name': self.au1.name},
|
||||
{'name': self.b2.name, 'author__name': self.au1.name},
|
||||
{'name': self.b3.name, 'author__name': self.au1.name},
|
||||
{'name': self.b7.name, 'author__name': self.au2.name},
|
||||
{'name': self.b1.name, 'author__name': self.au1.name},
|
||||
{'title': self.b5.title, 'author__name': self.au2.name},
|
||||
{'title': self.b6.title, 'author__name': self.au2.name},
|
||||
{'title': self.b4.title, 'author__name': self.au1.name},
|
||||
{'title': self.b2.title, 'author__name': self.au1.name},
|
||||
{'title': self.b3.title, 'author__name': self.au1.name},
|
||||
{'title': self.b7.title, 'author__name': self.au2.name},
|
||||
{'title': self.b1.title, 'author__name': self.au1.name},
|
||||
], transform=identity)
|
||||
self.assertQuerysetEqual(
|
||||
Author.objects.values('name', 'book__name').order_by('name', 'book__name'),
|
||||
Author.objects.values('name', 'book__title').order_by('name', 'book__title'),
|
||||
[
|
||||
{'name': self.au1.name, 'book__name': self.b1.name},
|
||||
{'name': self.au1.name, 'book__name': self.b2.name},
|
||||
{'name': self.au1.name, 'book__name': self.b3.name},
|
||||
{'name': self.au1.name, 'book__name': self.b4.name},
|
||||
{'name': self.au2.name, 'book__name': self.b5.name},
|
||||
{'name': self.au2.name, 'book__name': self.b6.name},
|
||||
{'name': self.au2.name, 'book__name': self.b7.name},
|
||||
{'name': self.au1.name, 'book__title': self.b1.title},
|
||||
{'name': self.au1.name, 'book__title': self.b2.title},
|
||||
{'name': self.au1.name, 'book__title': self.b3.title},
|
||||
{'name': self.au1.name, 'book__title': self.b4.title},
|
||||
{'name': self.au2.name, 'book__title': self.b5.title},
|
||||
{'name': self.au2.name, 'book__title': self.b6.title},
|
||||
{'name': self.au2.name, 'book__title': self.b7.title},
|
||||
], transform=identity)
|
||||
self.assertQuerysetEqual(
|
||||
Author.objects.values('name', 'book__name', 'book__tag__name').order_by('name', 'book__name', 'book__tag__name'),
|
||||
Author.objects.values('name', 'book__title', 'book__tag__name').order_by('name', 'book__title', 'book__tag__name'),
|
||||
[
|
||||
{'name': self.au1.name, 'book__name': self.b1.name, 'book__tag__name': self.t1.name},
|
||||
{'name': self.au1.name, 'book__name': self.b2.name, 'book__tag__name': self.t1.name},
|
||||
{'name': self.au1.name, 'book__name': self.b3.name, 'book__tag__name': self.t1.name},
|
||||
{'name': self.au1.name, 'book__name': self.b3.name, 'book__tag__name': self.t2.name},
|
||||
{'name': self.au1.name, 'book__name': self.b4.name, 'book__tag__name': self.t2.name},
|
||||
{'name': self.au2.name, 'book__name': self.b5.name, 'book__tag__name': self.t2.name},
|
||||
{'name': self.au2.name, 'book__name': self.b5.name, 'book__tag__name': self.t3.name},
|
||||
{'name': self.au2.name, 'book__name': self.b6.name, 'book__tag__name': self.t3.name},
|
||||
{'name': self.au2.name, 'book__name': self.b7.name, 'book__tag__name': self.t3.name},
|
||||
{'name': self.au1.name, 'book__title': self.b1.title, 'book__tag__name': self.t1.name},
|
||||
{'name': self.au1.name, 'book__title': self.b2.title, 'book__tag__name': self.t1.name},
|
||||
{'name': self.au1.name, 'book__title': self.b3.title, 'book__tag__name': self.t1.name},
|
||||
{'name': self.au1.name, 'book__title': self.b3.title, 'book__tag__name': self.t2.name},
|
||||
{'name': self.au1.name, 'book__title': self.b4.title, 'book__tag__name': self.t2.name},
|
||||
{'name': self.au2.name, 'book__title': self.b5.title, 'book__tag__name': self.t2.name},
|
||||
{'name': self.au2.name, 'book__title': self.b5.title, 'book__tag__name': self.t3.name},
|
||||
{'name': self.au2.name, 'book__title': self.b6.title, 'book__tag__name': self.t3.name},
|
||||
{'name': self.au2.name, 'book__title': self.b7.title, 'book__tag__name': self.t3.name},
|
||||
], transform=identity)
|
||||
# However, an exception FieldDoesNotExist will be thrown if you specify
|
||||
# a non-existent field name in values() (a field that is neither in the
|
||||
@ -249,7 +250,7 @@ class LookupTests(TestCase):
|
||||
[{
|
||||
'id': self.b5.id,
|
||||
'author_id': self.au2.id,
|
||||
'name': 'Book 5',
|
||||
'title': 'Book 5',
|
||||
'pages': 0,
|
||||
'pubdate': datetime(2005, 8, 1, 9, 0)
|
||||
}], transform=identity)
|
||||
@ -260,7 +261,7 @@ class LookupTests(TestCase):
|
||||
# Within each tuple, the order of the elements is the same as the order
|
||||
# of fields in the values_list() call.
|
||||
identity = lambda x:x
|
||||
self.assertQuerysetEqual(Book.objects.values_list('name'),
|
||||
self.assertQuerysetEqual(Book.objects.values_list('title'),
|
||||
[
|
||||
('Book 5',),
|
||||
('Book 6',),
|
||||
@ -309,19 +310,19 @@ class LookupTests(TestCase):
|
||||
],
|
||||
transform=identity)
|
||||
self.assertQuerysetEqual(
|
||||
Author.objects.values_list('name', 'book__name', 'book__tag__name').order_by('name', 'book__name', 'book__tag__name'),
|
||||
Author.objects.values_list('name', 'book__title', 'book__tag__name').order_by('name', 'book__title', 'book__tag__name'),
|
||||
[
|
||||
(self.au1.name, self.b1.name, self.t1.name),
|
||||
(self.au1.name, self.b2.name, self.t1.name),
|
||||
(self.au1.name, self.b3.name, self.t1.name),
|
||||
(self.au1.name, self.b3.name, self.t2.name),
|
||||
(self.au1.name, self.b4.name, self.t2.name),
|
||||
(self.au2.name, self.b5.name, self.t2.name),
|
||||
(self.au2.name, self.b5.name, self.t3.name),
|
||||
(self.au2.name, self.b6.name, self.t3.name),
|
||||
(self.au2.name, self.b7.name, self.t3.name),
|
||||
(self.au1.name, self.b1.title, self.t1.name),
|
||||
(self.au1.name, self.b2.title, self.t1.name),
|
||||
(self.au1.name, self.b3.title, self.t1.name),
|
||||
(self.au1.name, self.b3.title, self.t2.name),
|
||||
(self.au1.name, self.b4.title, self.t2.name),
|
||||
(self.au2.name, self.b5.title, self.t2.name),
|
||||
(self.au2.name, self.b5.title, self.t3.name),
|
||||
(self.au2.name, self.b6.title, self.t3.name),
|
||||
(self.au2.name, self.b7.title, self.t3.name),
|
||||
], transform=identity)
|
||||
self.assertRaises(TypeError, Book.objects.values_list, 'id', 'name', flat=True)
|
||||
self.assertRaises(TypeError, Book.objects.values_list, 'id', 'title', flat=True)
|
||||
|
||||
def test_get_next_previous_by(self):
|
||||
# Every DateField and DateTimeField creates get_next_by_FOO() and
|
||||
@ -332,7 +333,7 @@ class LookupTests(TestCase):
|
||||
'<Book: Book 2>')
|
||||
self.assertEqual(repr(self.b2.get_next_by_pubdate()),
|
||||
'<Book: Book 3>')
|
||||
self.assertEqual(repr(self.b2.get_next_by_pubdate(name__endswith='6')),
|
||||
self.assertEqual(repr(self.b2.get_next_by_pubdate(title__endswith='6')),
|
||||
'<Book: Book 6>')
|
||||
self.assertEqual(repr(self.b3.get_next_by_pubdate()),
|
||||
'<Book: Book 7>')
|
||||
@ -360,9 +361,9 @@ class LookupTests(TestCase):
|
||||
def test_escaping(self):
|
||||
# Underscores, percent signs and backslashes have special meaning in the
|
||||
# underlying SQL code, but Django handles the quoting of them automatically.
|
||||
b8 = Book(name='Book_ with underscore', pubdate=datetime(2005, 11, 20))
|
||||
b8 = Book(title='Book_ with underscore', pubdate=datetime(2005, 11, 20))
|
||||
b8.save()
|
||||
self.assertQuerysetEqual(Book.objects.filter(name__startswith='Book'),
|
||||
self.assertQuerysetEqual(Book.objects.filter(title__startswith='Book'),
|
||||
[
|
||||
'<Book: Book_ with underscore>',
|
||||
'<Book: Book 5>',
|
||||
@ -373,11 +374,11 @@ class LookupTests(TestCase):
|
||||
'<Book: Book 7>',
|
||||
'<Book: Book 1>',
|
||||
])
|
||||
self.assertQuerysetEqual(Book.objects.filter(name__startswith='Book_'),
|
||||
self.assertQuerysetEqual(Book.objects.filter(title__startswith='Book_'),
|
||||
['<Book: Book_ with underscore>'])
|
||||
b9 = Book(name='Book% with percent sign', pubdate=datetime(2005, 11, 21))
|
||||
b9 = Book(title='Book% with percent sign', pubdate=datetime(2005, 11, 21))
|
||||
b9.save()
|
||||
self.assertQuerysetEqual(Book.objects.filter(name__startswith='Book'),
|
||||
self.assertQuerysetEqual(Book.objects.filter(title__startswith='Book'),
|
||||
[
|
||||
'<Book: Book% with percent sign>',
|
||||
'<Book: Book_ with underscore>',
|
||||
@ -389,21 +390,21 @@ class LookupTests(TestCase):
|
||||
'<Book: Book 7>',
|
||||
'<Book: Book 1>',
|
||||
])
|
||||
self.assertQuerysetEqual(Book.objects.filter(name__startswith='Book%'),
|
||||
self.assertQuerysetEqual(Book.objects.filter(title__startswith='Book%'),
|
||||
['<Book: Book% with percent sign>'])
|
||||
b10 = Book(name='Book with \\ backslash', pubdate=datetime(2005, 11, 22))
|
||||
b10 = Book(title='Book with \\ backslash', pubdate=datetime(2005, 11, 22))
|
||||
b10.save()
|
||||
self.assertQuerysetEqual(Book.objects.filter(name__contains='\\'),
|
||||
self.assertQuerysetEqual(Book.objects.filter(title__contains='\\'),
|
||||
['<Book: Book with \ backslash>'])
|
||||
|
||||
def test_exclude(self):
|
||||
b8 = Book.objects.create(name='Book_ with underscore', pubdate=datetime(2005, 11, 20))
|
||||
b9 = Book.objects.create(name='Book% with percent sign', pubdate=datetime(2005, 11, 21))
|
||||
b10 = Book.objects.create(name='Book with \\ backslash', pubdate=datetime(2005, 11, 22))
|
||||
b8 = Book.objects.create(title='Book_ with underscore', pubdate=datetime(2005, 11, 20))
|
||||
b9 = Book.objects.create(title='Book% with percent sign', pubdate=datetime(2005, 11, 21))
|
||||
b10 = Book.objects.create(title='Book with \\ backslash', pubdate=datetime(2005, 11, 22))
|
||||
|
||||
# exclude() is the opposite of filter() when doing lookups:
|
||||
self.assertQuerysetEqual(
|
||||
Book.objects.filter(name__contains='Book').exclude(name__contains='with'),
|
||||
Book.objects.filter(title__contains='Book').exclude(title__contains='with'),
|
||||
[
|
||||
'<Book: Book 5>',
|
||||
'<Book: Book 6>',
|
||||
@ -413,7 +414,7 @@ class LookupTests(TestCase):
|
||||
'<Book: Book 7>',
|
||||
'<Book: Book 1>',
|
||||
])
|
||||
self.assertQuerysetEqual(Book.objects.exclude(name__startswith="Book_"),
|
||||
self.assertQuerysetEqual(Book.objects.exclude(title__startswith="Book_"),
|
||||
[
|
||||
'<Book: Book with \\ backslash>',
|
||||
'<Book: Book% with percent sign>',
|
||||
@ -425,7 +426,7 @@ class LookupTests(TestCase):
|
||||
'<Book: Book 7>',
|
||||
'<Book: Book 1>',
|
||||
])
|
||||
self.assertQuerysetEqual(Book.objects.exclude(name="Book 7"),
|
||||
self.assertQuerysetEqual(Book.objects.exclude(title="Book 7"),
|
||||
[
|
||||
'<Book: Book with \\ backslash>',
|
||||
'<Book: Book% with percent sign>',
|
||||
@ -442,12 +443,12 @@ class LookupTests(TestCase):
|
||||
# none() returns a QuerySet that behaves like any other QuerySet object
|
||||
self.assertQuerysetEqual(Book.objects.none(), [])
|
||||
self.assertQuerysetEqual(
|
||||
Book.objects.none().filter(name__startswith='Book'), [])
|
||||
Book.objects.none().filter(title__startswith='Book'), [])
|
||||
self.assertQuerysetEqual(
|
||||
Book.objects.filter(name__startswith='Book').none(), [])
|
||||
Book.objects.filter(title__startswith='Book').none(), [])
|
||||
self.assertEqual(Book.objects.none().count(), 0)
|
||||
self.assertEqual(
|
||||
Book.objects.none().update(name="This should not take effect"), 0)
|
||||
Book.objects.none().update(title="This should not take effect"), 0)
|
||||
self.assertQuerysetEqual(
|
||||
[article for article in Book.objects.none().iterator()],
|
||||
[])
|
||||
@ -468,46 +469,41 @@ class LookupTests(TestCase):
|
||||
|
||||
def test_error_messages(self):
|
||||
# Programming errors are pointed out with nice error messages
|
||||
try:
|
||||
Book.objects.filter(pubdate_year='2005').count()
|
||||
self.fail('FieldError not raised')
|
||||
except FieldError as ex:
|
||||
self.assertEqual(str(ex), "Cannot resolve keyword 'pubdate_year' "
|
||||
"into field. Choices are: author, id, name, pages, pubdate, tag, tags")
|
||||
try:
|
||||
Book.objects.filter(name__starts='Book')
|
||||
self.fail('FieldError not raised')
|
||||
except FieldError as ex:
|
||||
self.assertEqual(str(ex), "Join on field 'name' not permitted. "
|
||||
"Did you misspell 'starts' for the lookup type?")
|
||||
with six.assertRaisesRegex(self, FieldError, "Cannot resolve keyword 'pubdate_year' "
|
||||
"into field. Choices are: .+"):
|
||||
Book.objects.filter(pubdate_year='2005').count()
|
||||
|
||||
with self.assertRaises(FieldError, msg="Join on field 'title' not permitted. "
|
||||
"Did you misspell 'starts' for the lookup type?"):
|
||||
Book.objects.filter(title__starts='Book')
|
||||
|
||||
def test_regex(self):
|
||||
# Create some articles with a bit more interesting names for testing field lookups:
|
||||
for a in Book.objects.all():
|
||||
a.delete()
|
||||
now = datetime.now()
|
||||
b1 = Book(pubdate=now, name='f')
|
||||
b1 = Book(pubdate=now, title='f')
|
||||
b1.save()
|
||||
b2 = Book(pubdate=now, name='fo')
|
||||
b2 = Book(pubdate=now, title='fo')
|
||||
b2.save()
|
||||
b3 = Book(pubdate=now, name='foo')
|
||||
b3 = Book(pubdate=now, title='foo')
|
||||
b3.save()
|
||||
b4 = Book(pubdate=now, name='fooo')
|
||||
b4 = Book(pubdate=now, title='fooo')
|
||||
b4.save()
|
||||
b5 = Book(pubdate=now, name='hey-Foo')
|
||||
b5 = Book(pubdate=now, title='hey-Foo')
|
||||
b5.save()
|
||||
b6 = Book(pubdate=now, name='bar')
|
||||
b6 = Book(pubdate=now, title='bar')
|
||||
b6.save()
|
||||
b7 = Book(pubdate=now, name='AbBa')
|
||||
b7 = Book(pubdate=now, title='AbBa')
|
||||
b7.save()
|
||||
b8 = Book(pubdate=now, name='baz')
|
||||
b8 = Book(pubdate=now, title='baz')
|
||||
b8.save()
|
||||
b9 = Book(pubdate=now, name='baxZ')
|
||||
b9 = Book(pubdate=now, title='baxZ')
|
||||
b9.save()
|
||||
# zero-or-more
|
||||
self.assertQuerysetEqual(Book.objects.filter(name__regex=r'fo*'),
|
||||
self.assertQuerysetEqual(Book.objects.filter(title__regex=r'fo*'),
|
||||
['<Book: f>', '<Book: fo>', '<Book: foo>', '<Book: fooo>'])
|
||||
self.assertQuerysetEqual(Book.objects.filter(name__iregex=r'fo*'),
|
||||
self.assertQuerysetEqual(Book.objects.filter(title__iregex=r'fo*'),
|
||||
[
|
||||
'<Book: f>',
|
||||
'<Book: fo>',
|
||||
@ -516,54 +512,54 @@ class LookupTests(TestCase):
|
||||
'<Book: hey-Foo>',
|
||||
])
|
||||
# one-or-more
|
||||
self.assertQuerysetEqual(Book.objects.filter(name__regex=r'fo+'),
|
||||
self.assertQuerysetEqual(Book.objects.filter(title__regex=r'fo+'),
|
||||
['<Book: fo>', '<Book: foo>', '<Book: fooo>'])
|
||||
# wildcard
|
||||
self.assertQuerysetEqual(Book.objects.filter(name__regex=r'fooo?'),
|
||||
self.assertQuerysetEqual(Book.objects.filter(title__regex=r'fooo?'),
|
||||
['<Book: foo>', '<Book: fooo>'])
|
||||
# leading anchor
|
||||
self.assertQuerysetEqual(Book.objects.filter(name__regex=r'^b'),
|
||||
self.assertQuerysetEqual(Book.objects.filter(title__regex=r'^b'),
|
||||
['<Book: bar>', '<Book: baxZ>', '<Book: baz>'])
|
||||
self.assertQuerysetEqual(Book.objects.filter(name__iregex=r'^a'),
|
||||
self.assertQuerysetEqual(Book.objects.filter(title__iregex=r'^a'),
|
||||
['<Book: AbBa>'])
|
||||
# trailing anchor
|
||||
self.assertQuerysetEqual(Book.objects.filter(name__regex=r'z$'),
|
||||
self.assertQuerysetEqual(Book.objects.filter(title__regex=r'z$'),
|
||||
['<Book: baz>'])
|
||||
self.assertQuerysetEqual(Book.objects.filter(name__iregex=r'z$'),
|
||||
self.assertQuerysetEqual(Book.objects.filter(title__iregex=r'z$'),
|
||||
['<Book: baxZ>', '<Book: baz>'])
|
||||
# character sets
|
||||
self.assertQuerysetEqual(Book.objects.filter(name__regex=r'ba[rz]'),
|
||||
self.assertQuerysetEqual(Book.objects.filter(title__regex=r'ba[rz]'),
|
||||
['<Book: bar>', '<Book: baz>'])
|
||||
self.assertQuerysetEqual(Book.objects.filter(name__regex=r'ba.[RxZ]'),
|
||||
self.assertQuerysetEqual(Book.objects.filter(title__regex=r'ba.[RxZ]'),
|
||||
['<Book: baxZ>'])
|
||||
self.assertQuerysetEqual(Book.objects.filter(name__iregex=r'ba[RxZ]'),
|
||||
self.assertQuerysetEqual(Book.objects.filter(title__iregex=r'ba[RxZ]'),
|
||||
['<Book: bar>', '<Book: baxZ>', '<Book: baz>'])
|
||||
|
||||
# and more articles:
|
||||
b10 = Book(pubdate=now, name='foobar')
|
||||
b10 = Book(pubdate=now, title='foobar')
|
||||
b10.save()
|
||||
b11 = Book(pubdate=now, name='foobaz')
|
||||
b11 = Book(pubdate=now, title='foobaz')
|
||||
b11.save()
|
||||
b12 = Book(pubdate=now, name='ooF')
|
||||
b12 = Book(pubdate=now, title='ooF')
|
||||
b12.save()
|
||||
b13 = Book(pubdate=now, name='foobarbaz')
|
||||
b13 = Book(pubdate=now, title='foobarbaz')
|
||||
b13.save()
|
||||
b14 = Book(pubdate=now, name='zoocarfaz')
|
||||
b14 = Book(pubdate=now, title='zoocarfaz')
|
||||
b14.save()
|
||||
b15 = Book(pubdate=now, name='barfoobaz')
|
||||
b15 = Book(pubdate=now, title='barfoobaz')
|
||||
b15.save()
|
||||
b16 = Book(pubdate=now, name='bazbaRFOO')
|
||||
b16 = Book(pubdate=now, title='bazbaRFOO')
|
||||
b16.save()
|
||||
|
||||
# alternation
|
||||
self.assertQuerysetEqual(Book.objects.filter(name__regex=r'oo(f|b)'),
|
||||
self.assertQuerysetEqual(Book.objects.filter(title__regex=r'oo(f|b)'),
|
||||
[
|
||||
'<Book: barfoobaz>',
|
||||
'<Book: foobar>',
|
||||
'<Book: foobarbaz>',
|
||||
'<Book: foobaz>',
|
||||
])
|
||||
self.assertQuerysetEqual(Book.objects.filter(name__iregex=r'oo(f|b)'),
|
||||
self.assertQuerysetEqual(Book.objects.filter(title__iregex=r'oo(f|b)'),
|
||||
[
|
||||
'<Book: barfoobaz>',
|
||||
'<Book: foobar>',
|
||||
@ -571,11 +567,11 @@ class LookupTests(TestCase):
|
||||
'<Book: foobaz>',
|
||||
'<Book: ooF>',
|
||||
])
|
||||
self.assertQuerysetEqual(Book.objects.filter(name__regex=r'^foo(f|b)'),
|
||||
self.assertQuerysetEqual(Book.objects.filter(title__regex=r'^foo(f|b)'),
|
||||
['<Book: foobar>', '<Book: foobarbaz>', '<Book: foobaz>'])
|
||||
|
||||
# greedy matching
|
||||
self.assertQuerysetEqual(Book.objects.filter(name__regex=r'b.*az'),
|
||||
self.assertQuerysetEqual(Book.objects.filter(title__regex=r'b.*az'),
|
||||
[
|
||||
'<Book: barfoobaz>',
|
||||
'<Book: baz>',
|
||||
@ -583,7 +579,7 @@ class LookupTests(TestCase):
|
||||
'<Book: foobarbaz>',
|
||||
'<Book: foobaz>',
|
||||
])
|
||||
self.assertQuerysetEqual(Book.objects.filter(name__iregex=r'b.*ar'),
|
||||
self.assertQuerysetEqual(Book.objects.filter(title__iregex=r'b.*ar'),
|
||||
[
|
||||
'<Book: bar>',
|
||||
'<Book: barfoobaz>',
|
||||
@ -596,21 +592,21 @@ class LookupTests(TestCase):
|
||||
def test_regex_backreferencing(self):
|
||||
# grouping and backreferences
|
||||
now = datetime.now()
|
||||
b10 = Book(pubdate=now, name='foobar')
|
||||
b10 = Book(pubdate=now, title='foobar')
|
||||
b10.save()
|
||||
b11 = Book(pubdate=now, name='foobaz')
|
||||
b11 = Book(pubdate=now, title='foobaz')
|
||||
b11.save()
|
||||
b12 = Book(pubdate=now, name='ooF')
|
||||
b12 = Book(pubdate=now, title='ooF')
|
||||
b12.save()
|
||||
b13 = Book(pubdate=now, name='foobarbaz')
|
||||
b13 = Book(pubdate=now, title='foobarbaz')
|
||||
b13.save()
|
||||
b14 = Book(pubdate=now, name='zoocarfaz')
|
||||
b14 = Book(pubdate=now, title='zoocarfaz')
|
||||
b14.save()
|
||||
b15 = Book(pubdate=now, name='barfoobaz')
|
||||
b15 = Book(pubdate=now, title='barfoobaz')
|
||||
b15.save()
|
||||
b16 = Book(pubdate=now, name='bazbaRFOO')
|
||||
b16 = Book(pubdate=now, title='bazbaRFOO')
|
||||
b16.save()
|
||||
self.assertQuerysetEqual(Book.objects.filter(name__regex=r'b(.).*b\1'),
|
||||
self.assertQuerysetEqual(Book.objects.filter(title__regex=r'b(.).*b\1'),
|
||||
['<Book: barfoobaz>', '<Book: bazbaRFOO>', '<Book: foobarbaz>'])
|
||||
|
||||
def test_nonfield_lookups(self):
|
||||
|
@ -16,6 +16,7 @@ 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)
|
||||
@ -44,23 +45,13 @@ class Category(models.Model):
|
||||
def __repr__(self):
|
||||
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(Writer)
|
||||
writer = models.ForeignKey(Author)
|
||||
article = models.TextField()
|
||||
categories = models.ManyToManyField(Category, blank=True)
|
||||
status = models.PositiveIntegerField(choices=ARTICLE_STATUS, blank=True, null=True)
|
||||
@ -80,12 +71,12 @@ class ImprovedArticle(models.Model):
|
||||
class ImprovedArticleWithParentLink(models.Model):
|
||||
article = models.OneToOneField(Article, parent_link=True)
|
||||
|
||||
class BetterWriter(Writer):
|
||||
class BetterAuthor(Author):
|
||||
score = models.IntegerField()
|
||||
|
||||
@python_2_unicode_compatible
|
||||
class WriterProfile(models.Model):
|
||||
writer = models.OneToOneField(Writer, primary_key=True)
|
||||
class AuthorProfile(models.Model):
|
||||
writer = models.OneToOneField(Author, primary_key=True)
|
||||
age = models.PositiveIntegerField()
|
||||
|
||||
def __str__(self):
|
||||
@ -192,14 +183,6 @@ 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)
|
||||
|
@ -15,11 +15,13 @@ from django.utils.unittest import skipUnless
|
||||
from django.test import TestCase
|
||||
from django.utils import six
|
||||
|
||||
from .models import (Article, ArticleStatus, BetterWriter, BigInt, Book,
|
||||
from shared_models.models import Author, Book
|
||||
|
||||
from .models import (Article, ArticleStatus, BetterAuthor, BigInt,
|
||||
Category, CommaSeparatedInteger, CustomFieldForExclusionModel, DerivedBook,
|
||||
DerivedPost, ExplicitPK, FlexibleDatePost, ImprovedArticle,
|
||||
ImprovedArticleWithParentLink, Inventory, Post, Price,
|
||||
Product, TextFile, Writer, WriterProfile, Colour, ColourfulItem,
|
||||
Product, TextFile, AuthorProfile, Colour, ColourfulItem,
|
||||
test_images)
|
||||
|
||||
if test_images:
|
||||
@ -44,11 +46,13 @@ class PriceForm(forms.ModelForm):
|
||||
|
||||
class BookForm(forms.ModelForm):
|
||||
class Meta:
|
||||
model = Book
|
||||
fields = ['title', 'author', 'pubdate']
|
||||
model = Book
|
||||
|
||||
|
||||
class DerivedBookForm(forms.ModelForm):
|
||||
class Meta:
|
||||
fields = ['title', 'author', 'isbn', 'suffix1', 'suffix2']
|
||||
model = DerivedBook
|
||||
|
||||
|
||||
@ -68,11 +72,11 @@ class DerivedPostForm(forms.ModelForm):
|
||||
model = DerivedPost
|
||||
|
||||
|
||||
class CustomWriterForm(forms.ModelForm):
|
||||
class CustomAuthorForm(forms.ModelForm):
|
||||
name = forms.CharField(required=False)
|
||||
|
||||
class Meta:
|
||||
model = Writer
|
||||
model = Author
|
||||
|
||||
|
||||
class FlexDatePostForm(forms.ModelForm):
|
||||
@ -101,7 +105,7 @@ class PartialArticleForm(forms.ModelForm):
|
||||
|
||||
class RoykoForm(forms.ModelForm):
|
||||
class Meta:
|
||||
model = Writer
|
||||
model = Author
|
||||
|
||||
class TestArticleForm(forms.ModelForm):
|
||||
class Meta:
|
||||
@ -144,13 +148,13 @@ class ImprovedArticleWithParentLinkForm(forms.ModelForm):
|
||||
class Meta:
|
||||
model = ImprovedArticleWithParentLink
|
||||
|
||||
class BetterWriterForm(forms.ModelForm):
|
||||
class BetterAuthorForm(forms.ModelForm):
|
||||
class Meta:
|
||||
model = BetterWriter
|
||||
model = BetterAuthor
|
||||
|
||||
class WriterProfileForm(forms.ModelForm):
|
||||
class AuthorProfileForm(forms.ModelForm):
|
||||
class Meta:
|
||||
model = WriterProfile
|
||||
model = AuthorProfile
|
||||
|
||||
class TextFileForm(forms.ModelForm):
|
||||
class Meta:
|
||||
@ -206,13 +210,13 @@ class ModelFormBaseTest(TestCase):
|
||||
forms.fields.BooleanField))
|
||||
|
||||
def test_override_field(self):
|
||||
class WriterForm(forms.ModelForm):
|
||||
class AuthorForm(forms.ModelForm):
|
||||
book = forms.CharField(required=False)
|
||||
|
||||
class Meta:
|
||||
model = Writer
|
||||
model = Author
|
||||
|
||||
wf = WriterForm({'name': 'Richard Lockridge'})
|
||||
wf = AuthorForm({'name': 'Richard Lockridge'})
|
||||
self.assertTrue(wf.is_valid())
|
||||
|
||||
def test_limit_fields(self):
|
||||
@ -411,7 +415,7 @@ class ValidationTest(TestCase):
|
||||
assert form.is_valid()
|
||||
|
||||
def test_notrequired_overrides_notblank(self):
|
||||
form = CustomWriterForm({})
|
||||
form = CustomAuthorForm({})
|
||||
assert form.is_valid()
|
||||
|
||||
|
||||
@ -420,7 +424,7 @@ class ValidationTest(TestCase):
|
||||
# unique/unique_together validation
|
||||
class UniqueTest(TestCase):
|
||||
def setUp(self):
|
||||
self.writer = Writer.objects.create(name='Mike Royko')
|
||||
self.author = Author.objects.create(name='Mike Royko')
|
||||
|
||||
def test_simple_unique(self):
|
||||
form = ProductForm({'slug': 'teddy-bear-blue'})
|
||||
@ -444,33 +448,31 @@ class UniqueTest(TestCase):
|
||||
|
||||
def test_unique_null(self):
|
||||
title = 'I May Be Wrong But I Doubt It'
|
||||
form = BookForm({'title': title, 'author': self.writer.pk})
|
||||
form = BookForm({'title': title, 'author': self.author.pk, 'pubdate': '2012-12-12 00:00:00'})
|
||||
self.assertTrue(form.is_valid())
|
||||
form.save()
|
||||
form = BookForm({'title': title, 'author': self.writer.pk})
|
||||
form = BookForm({'title': title, 'author': self.author.pk, 'pubdate': '2012-12-12 00:00:00'})
|
||||
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})
|
||||
form = BookForm({'title': title, 'pubdate': '2012-12-12 00:00:00'})
|
||||
self.assertTrue(form.is_valid())
|
||||
form.save()
|
||||
form = BookForm({'title': title})
|
||||
form = BookForm({'title': title, 'pubdate': '2012-12-12 00:00:00'})
|
||||
self.assertTrue(form.is_valid())
|
||||
|
||||
def test_inherited_unique(self):
|
||||
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'})
|
||||
form = BetterAuthorForm({'name': 'Mike Royko', 'score': 3})
|
||||
self.assertFalse(form.is_valid())
|
||||
self.assertEqual(len(form.errors), 1)
|
||||
self.assertEqual(form.errors['special_id'], ['Book with this Special id already exists.'])
|
||||
self.assertEqual(form.errors['name'], ['Author with this Name already exists.'])
|
||||
|
||||
def test_inherited_unique_together(self):
|
||||
title = 'Boss'
|
||||
form = BookForm({'title': title, 'author': self.writer.pk})
|
||||
form = BookForm({'title': title, 'author': self.author.pk, 'pubdate': '2012-12-12 00:00:00'})
|
||||
self.assertTrue(form.is_valid())
|
||||
form.save()
|
||||
form = DerivedBookForm({'title': title, 'author': self.writer.pk, 'isbn': '12345'})
|
||||
form = DerivedBookForm({'title': title, 'author': self.author.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.'])
|
||||
@ -478,8 +480,9 @@ class UniqueTest(TestCase):
|
||||
def test_abstract_inherited_unique(self):
|
||||
title = 'Boss'
|
||||
isbn = '12345'
|
||||
dbook = DerivedBook.objects.create(title=title, author=self.writer, isbn=isbn)
|
||||
form = DerivedBookForm({'title': 'Other', 'author': self.writer.pk, 'isbn': isbn})
|
||||
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})
|
||||
self.assertFalse(form.is_valid())
|
||||
self.assertEqual(len(form.errors), 1)
|
||||
self.assertEqual(form.errors['isbn'], ['Derived book with this Isbn already exists.'])
|
||||
@ -487,10 +490,11 @@ class UniqueTest(TestCase):
|
||||
def test_abstract_inherited_unique_together(self):
|
||||
title = 'Boss'
|
||||
isbn = '12345'
|
||||
dbook = DerivedBook.objects.create(title=title, author=self.writer, isbn=isbn)
|
||||
dbook = DerivedBook.objects.create(title=title, author=self.author, isbn=isbn,
|
||||
pubdate='2012-12-12 00:00')
|
||||
form = DerivedBookForm({
|
||||
'title': 'Other',
|
||||
'author': self.writer.pk,
|
||||
'author': self.author.pk,
|
||||
'isbn': '9876',
|
||||
'suffix1': '0',
|
||||
'suffix2': '0'
|
||||
@ -591,7 +595,7 @@ class ModelToDictTests(TestCase):
|
||||
]
|
||||
for c in categories:
|
||||
c.save()
|
||||
writer = Writer(name='Test writer')
|
||||
writer = Author(name='Test writer')
|
||||
writer.save()
|
||||
|
||||
art = Article(
|
||||
@ -700,10 +704,10 @@ class OldFormForXTests(TestCase):
|
||||
with self.assertRaises(ValueError):
|
||||
f.save()
|
||||
|
||||
# Create a couple of Writers.
|
||||
w_royko = Writer(name='Mike Royko')
|
||||
# Create a couple of Authors.
|
||||
w_royko = Author(name='Mike Royko')
|
||||
w_royko.save()
|
||||
w_woodward = Writer(name='Bob Woodward')
|
||||
w_woodward = Author(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.
|
||||
@ -741,9 +745,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 = Writer.objects.get(name='Mike Royko')
|
||||
w = Author.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="50" /><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="100" /><br /><span class="helptext">Use both first and last names.</span></td></tr>''')
|
||||
|
||||
art = Article(
|
||||
headline='Test article',
|
||||
@ -955,7 +959,7 @@ class OldFormForXTests(TestCase):
|
||||
|
||||
c4 = Category.objects.create(name='Fourth', url='4th')
|
||||
self.assertEqual(c4.name, 'Fourth')
|
||||
w_bernstein = Writer.objects.create(name='Carl Bernstein')
|
||||
w_bernstein = Author.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>
|
||||
@ -1132,17 +1136,17 @@ class OldFormForXTests(TestCase):
|
||||
|
||||
self.assertEqual(list(ImprovedArticleWithParentLinkForm.base_fields), [])
|
||||
|
||||
bw = BetterWriter(name='Joe Better', score=10)
|
||||
bw = BetterAuthor(name='Joe Better', score=10)
|
||||
bw.save()
|
||||
self.assertEqual(sorted(model_to_dict(bw)),
|
||||
['id', 'name', 'score', 'writer_ptr'])
|
||||
['author_ptr', 'id', 'name', 'score'])
|
||||
|
||||
form = BetterWriterForm({'name': 'Some Name', 'score': 12})
|
||||
form = BetterAuthorForm({'name': 'Some Name', 'score': 12})
|
||||
self.assertEqual(form.is_valid(), True)
|
||||
bw2 = form.save()
|
||||
bw2.delete()
|
||||
|
||||
form = WriterProfileForm()
|
||||
form = AuthorProfileForm()
|
||||
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>
|
||||
@ -1156,11 +1160,11 @@ class OldFormForXTests(TestCase):
|
||||
'writer': six.text_type(w_woodward.pk),
|
||||
'age': '65',
|
||||
}
|
||||
form = WriterProfileForm(data)
|
||||
form = AuthorProfileForm(data)
|
||||
instance = form.save()
|
||||
self.assertEqual(six.text_type(instance), 'Bob Woodward is 65')
|
||||
|
||||
form = WriterProfileForm(instance=instance)
|
||||
form = AuthorProfileForm(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>
|
||||
|
@ -1,3 +1,5 @@
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from django.db import models
|
||||
from django.utils import timezone
|
||||
from django.utils.encoding import python_2_unicode_compatible
|
||||
@ -9,7 +11,11 @@ class Tag(models.Model):
|
||||
|
||||
@python_2_unicode_compatible
|
||||
class Author(models.Model):
|
||||
name = models.CharField(max_length=100)
|
||||
name = models.CharField(max_length=100, help_text='Use both first and last names.',
|
||||
unique=True)
|
||||
|
||||
class Meta:
|
||||
ordering = ['name']
|
||||
|
||||
def __str__(self):
|
||||
return self.name
|
||||
@ -17,14 +23,15 @@ class Author(models.Model):
|
||||
|
||||
@python_2_unicode_compatible
|
||||
class Book(models.Model):
|
||||
name = models.CharField(max_length=200)
|
||||
title = models.CharField(max_length=200)
|
||||
pages = models.IntegerField(default=0)
|
||||
author = models.ForeignKey(Author, null=True)
|
||||
author = models.ForeignKey(Author, null=True, blank=True)
|
||||
pubdate = models.DateTimeField()
|
||||
tags = models.ManyToManyField(Tag)
|
||||
|
||||
class Meta:
|
||||
ordering = ['-pubdate', 'name']
|
||||
ordering = ['-pubdate', 'title']
|
||||
unique_together = ['title', 'author']
|
||||
|
||||
def __str__(self):
|
||||
return self.name
|
||||
return self.title
|
||||
|
@ -77,7 +77,7 @@ class SignalsRegressTests(TestCase):
|
||||
"Is created"
|
||||
])
|
||||
|
||||
b1 = Book(name='Snow Crash', pubdate='2012-02-02 12:00')
|
||||
b1 = Book(title='Snow Crash', pubdate='2012-02-02 12:00')
|
||||
self.assertEqual(self.get_signal_output(b1.save), [
|
||||
"pre_save signal, Snow Crash",
|
||||
"post_save signal, Snow Crash",
|
||||
@ -87,7 +87,7 @@ class SignalsRegressTests(TestCase):
|
||||
def test_m2m_signals(self):
|
||||
""" Assigning and removing to/from m2m shouldn't generate an m2m signal """
|
||||
|
||||
b1 = Book(name='Snow Crash', pubdate='2012-02-02 12:00')
|
||||
b1 = Book(title='Snow Crash', pubdate='2012-02-02 12:00')
|
||||
self.get_signal_output(b1.save)
|
||||
a1 = Author(name='Neal Stephenson')
|
||||
self.get_signal_output(a1.save)
|
||||
|
Loading…
Reference in New Issue
Block a user