Began implementing a shared set of test models to speed up tests.

This commit is contained in:
Florian Apolloner 2013-03-13 23:25:26 +01:00
parent 1059da8de6
commit 22b7870e40
5 changed files with 205 additions and 215 deletions

View File

@ -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):

View File

@ -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)

View File

@ -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>

View File

@ -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

View File

@ -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)