Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Merge pull request #900 from bmispelon/ticket-20022

Fix #20022: Correctly handle prefixes with url-unsafe characters in reverse()
  • Loading branch information...
commit 1059da8de675442e84381d6366c0be254681753e 2 parents 5d8342f + 4fa7f3c
@jacobian jacobian authored apollo13 committed
View
2  django/core/urlresolvers.py
@@ -388,7 +388,7 @@ def _reverse_with_prefix(self, lookup_view, _prefix, *args, **kwargs):
if len(args) != len(params) + len(prefix_args):
continue
unicode_args = [force_text(val) for val in args]
- candidate = (prefix_norm + result) % dict(zip(prefix_args + params, unicode_args))
+ candidate = (prefix_norm.replace('%', '%%') + result) % dict(zip(prefix_args + params, unicode_args))
else:
if set(kwargs.keys()) | set(defaults.keys()) != set(params) | set(defaults.keys()) | set(prefix_args):
continue
View
21 tests/lookup/models.py
@@ -10,29 +10,16 @@
from django.utils import six
from django.utils.encoding import python_2_unicode_compatible
+from shared_models.models import Author, Book
-class Author(models.Model):
- name = models.CharField(max_length=100)
- class Meta:
- ordering = ('name', )
-
-@python_2_unicode_compatible
-class Article(models.Model):
- headline = models.CharField(max_length=100)
- pub_date = models.DateTimeField()
- author = models.ForeignKey(Author, blank=True, null=True)
- class Meta:
- ordering = ('-pub_date', 'headline')
-
- def __str__(self):
- return self.headline
class Tag(models.Model):
- articles = models.ManyToManyField(Article)
+ articles = models.ManyToManyField(Book)
name = models.CharField(max_length=100)
class Meta:
ordering = ('name', )
+
@python_2_unicode_compatible
class Season(models.Model):
year = models.PositiveSmallIntegerField()
@@ -41,6 +28,7 @@ class Season(models.Model):
def __str__(self):
return six.text_type(self.year)
+
@python_2_unicode_compatible
class Game(models.Model):
season = models.ForeignKey(Season, related_name='games')
@@ -50,6 +38,7 @@ class Game(models.Model):
def __str__(self):
return "%s at %s" % (self.away, self.home)
+
@python_2_unicode_compatible
class Player(models.Model):
name = models.CharField(max_length=100)
View
785 tests/lookup/tests.py
@@ -6,7 +6,9 @@
from django.core.exceptions import FieldError
from django.test import TestCase, skipUnlessDBFeature
-from .models import Author, Article, Tag, Game, Season, Player
+from shared_models.models import Author, Book
+
+from .models import Tag, Game, Season, Player
class LookupTests(TestCase):
@@ -17,165 +19,165 @@ def setUp(self):
self.au1.save()
self.au2 = Author(name='Author 2')
self.au2.save()
- # Create a couple of Articles.
- self.a1 = Article(headline='Article 1', pub_date=datetime(2005, 7, 26), author=self.au1)
- self.a1.save()
- self.a2 = Article(headline='Article 2', pub_date=datetime(2005, 7, 27), author=self.au1)
- self.a2.save()
- self.a3 = Article(headline='Article 3', pub_date=datetime(2005, 7, 27), author=self.au1)
- self.a3.save()
- self.a4 = Article(headline='Article 4', pub_date=datetime(2005, 7, 28), author=self.au1)
- self.a4.save()
- self.a5 = Article(headline='Article 5', pub_date=datetime(2005, 8, 1, 9, 0), author=self.au2)
- self.a5.save()
- self.a6 = Article(headline='Article 6', pub_date=datetime(2005, 8, 1, 8, 0), author=self.au2)
- self.a6.save()
- self.a7 = Article(headline='Article 7', pub_date=datetime(2005, 7, 27), author=self.au2)
- self.a7.save()
+ # Create a couple of Books.
+ self.b1 = Book(name='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.save()
+ self.b3 = Book(name='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.save()
+ self.b5 = Book(name='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.save()
+ self.b7 = Book(name='Book 7', pubdate=datetime(2005, 7, 27), author=self.au2)
+ self.b7.save()
# Create a few Tags.
self.t1 = Tag(name='Tag 1')
self.t1.save()
- self.t1.articles.add(self.a1, self.a2, self.a3)
+ self.t1.articles.add(self.b1, self.b2, self.b3)
self.t2 = Tag(name='Tag 2')
self.t2.save()
- self.t2.articles.add(self.a3, self.a4, self.a5)
+ self.t2.articles.add(self.b3, self.b4, self.b5)
self.t3 = Tag(name='Tag 3')
self.t3.save()
- self.t3.articles.add(self.a5, self.a6, self.a7)
+ self.t3.articles.add(self.b5, self.b6, self.b7)
def test_exists(self):
# We can use .exists() to check that there are some
- self.assertTrue(Article.objects.exists())
- for a in Article.objects.all():
+ self.assertTrue(Book.objects.exists())
+ for a in Book.objects.all():
a.delete()
# There should be none now!
- self.assertFalse(Article.objects.exists())
+ self.assertFalse(Book.objects.exists())
def test_lookup_int_as_str(self):
# Integer value can be queried using string
- self.assertQuerysetEqual(Article.objects.filter(id__iexact=str(self.a1.id)),
- ['<Article: Article 1>'])
+ self.assertQuerysetEqual(Book.objects.filter(id__iexact=str(self.b1.id)),
+ ['<Book: Book 1>'])
@skipUnlessDBFeature('supports_date_lookup_using_string')
def test_lookup_date_as_str(self):
# A date lookup can be performed using a string search
- self.assertQuerysetEqual(Article.objects.filter(pub_date__startswith='2005'),
+ self.assertQuerysetEqual(Book.objects.filter(pubdate__startswith='2005'),
[
- '<Article: Article 5>',
- '<Article: Article 6>',
- '<Article: Article 4>',
- '<Article: Article 2>',
- '<Article: Article 3>',
- '<Article: Article 7>',
- '<Article: Article 1>',
+ '<Book: Book 5>',
+ '<Book: Book 6>',
+ '<Book: Book 4>',
+ '<Book: Book 2>',
+ '<Book: Book 3>',
+ '<Book: Book 7>',
+ '<Book: Book 1>',
])
def test_iterator(self):
# Each QuerySet gets iterator(), which is a generator that "lazily"
# returns results using database-level iteration.
- self.assertQuerysetEqual(Article.objects.iterator(),
+ self.assertQuerysetEqual(Book.objects.iterator(),
[
- 'Article 5',
- 'Article 6',
- 'Article 4',
- 'Article 2',
- 'Article 3',
- 'Article 7',
- 'Article 1',
+ 'Book 5',
+ 'Book 6',
+ 'Book 4',
+ 'Book 2',
+ 'Book 3',
+ 'Book 7',
+ 'Book 1',
],
- transform=attrgetter('headline'))
+ transform=attrgetter('name'))
# iterator() can be used on any QuerySet.
self.assertQuerysetEqual(
- Article.objects.filter(headline__endswith='4').iterator(),
- ['Article 4'],
- transform=attrgetter('headline'))
+ Book.objects.filter(name__endswith='4').iterator(),
+ ['Book 4'],
+ transform=attrgetter('name'))
def test_count(self):
# count() returns the number of objects matching search criteria.
- self.assertEqual(Article.objects.count(), 7)
- self.assertEqual(Article.objects.filter(pub_date__exact=datetime(2005, 7, 27)).count(), 3)
- self.assertEqual(Article.objects.filter(headline__startswith='Blah blah').count(), 0)
+ 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)
# count() should respect sliced query sets.
- articles = Article.objects.all()
+ articles = Book.objects.all()
self.assertEqual(articles.count(), 7)
self.assertEqual(articles[:4].count(), 4)
self.assertEqual(articles[1:100].count(), 6)
self.assertEqual(articles[10:100].count(), 0)
# Date and date/time lookups can also be done with strings.
- self.assertEqual(Article.objects.filter(pub_date__exact='2005-07-27 00:00:00').count(), 3)
+ self.assertEqual(Book.objects.filter(pubdate__exact='2005-07-27').count(), 3)
def test_in_bulk(self):
# in_bulk() takes a list of IDs and returns a dictionary mapping IDs to objects.
- arts = Article.objects.in_bulk([self.a1.id, self.a2.id])
- self.assertEqual(arts[self.a1.id], self.a1)
- self.assertEqual(arts[self.a2.id], self.a2)
- self.assertEqual(Article.objects.in_bulk([self.a3.id]), {self.a3.id: self.a3})
- self.assertEqual(Article.objects.in_bulk(set([self.a3.id])), {self.a3.id: self.a3})
- self.assertEqual(Article.objects.in_bulk(frozenset([self.a3.id])), {self.a3.id: self.a3})
- self.assertEqual(Article.objects.in_bulk((self.a3.id,)), {self.a3.id: self.a3})
- self.assertEqual(Article.objects.in_bulk([1000]), {})
- self.assertEqual(Article.objects.in_bulk([]), {})
- self.assertEqual(Article.objects.in_bulk(iter([self.a1.id])), {self.a1.id: self.a1})
- self.assertEqual(Article.objects.in_bulk(iter([])), {})
- self.assertRaises(TypeError, Article.objects.in_bulk)
- self.assertRaises(TypeError, Article.objects.in_bulk, headline__startswith='Blah')
+ arts = Book.objects.in_bulk([self.b1.id, self.b2.id])
+ self.assertEqual(arts[self.b1.id], self.b1)
+ self.assertEqual(arts[self.b2.id], self.b2)
+ self.assertEqual(Book.objects.in_bulk([self.b3.id]), {self.b3.id: self.b3})
+ self.assertEqual(Book.objects.in_bulk(set([self.b3.id])), {self.b3.id: self.b3})
+ self.assertEqual(Book.objects.in_bulk(frozenset([self.b3.id])), {self.b3.id: self.b3})
+ self.assertEqual(Book.objects.in_bulk((self.b3.id,)), {self.b3.id: self.b3})
+ self.assertEqual(Book.objects.in_bulk([1000]), {})
+ self.assertEqual(Book.objects.in_bulk([]), {})
+ self.assertEqual(Book.objects.in_bulk(iter([self.b1.id])), {self.b1.id: self.b1})
+ self.assertEqual(Book.objects.in_bulk(iter([])), {})
+ self.assertRaises(TypeError, Book.objects.in_bulk)
+ self.assertRaises(TypeError, Book.objects.in_bulk, name__startswith='Blah')
def test_values(self):
# 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(Article.objects.values('headline'),
+ self.assertQuerysetEqual(Book.objects.values('name'),
[
- {'headline': 'Article 5'},
- {'headline': 'Article 6'},
- {'headline': 'Article 4'},
- {'headline': 'Article 2'},
- {'headline': 'Article 3'},
- {'headline': 'Article 7'},
- {'headline': 'Article 1'},
+ {'name': 'Book 5'},
+ {'name': 'Book 6'},
+ {'name': 'Book 4'},
+ {'name': 'Book 2'},
+ {'name': 'Book 3'},
+ {'name': 'Book 7'},
+ {'name': 'Book 1'},
],
transform=identity)
self.assertQuerysetEqual(
- Article.objects.filter(pub_date__exact=datetime(2005, 7, 27)).values('id'),
- [{'id': self.a2.id}, {'id': self.a3.id}, {'id': self.a7.id}],
+ 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(Article.objects.values('id', 'headline'),
+ self.assertQuerysetEqual(Book.objects.values('id', 'name'),
[
- {'id': self.a5.id, 'headline': 'Article 5'},
- {'id': self.a6.id, 'headline': 'Article 6'},
- {'id': self.a4.id, 'headline': 'Article 4'},
- {'id': self.a2.id, 'headline': 'Article 2'},
- {'id': self.a3.id, 'headline': 'Article 3'},
- {'id': self.a7.id, 'headline': 'Article 7'},
- {'id': self.a1.id, 'headline': 'Article 1'},
+ {'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'},
],
transform=identity)
# You can use values() with iterator() for memory savings,
# because iterator() uses database-level iteration.
- self.assertQuerysetEqual(Article.objects.values('id', 'headline').iterator(),
+ self.assertQuerysetEqual(Book.objects.values('id', 'name').iterator(),
[
- {'headline': 'Article 5', 'id': self.a5.id},
- {'headline': 'Article 6', 'id': self.a6.id},
- {'headline': 'Article 4', 'id': self.a4.id},
- {'headline': 'Article 2', 'id': self.a2.id},
- {'headline': 'Article 3', 'id': self.a3.id},
- {'headline': 'Article 7', 'id': self.a7.id},
- {'headline': 'Article 1', 'id': self.a1.id},
+ {'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},
],
transform=identity)
# The values() method works with "extra" fields specified in extra(select).
self.assertQuerysetEqual(
- Article.objects.extra(select={'id_plus_one': 'id + 1'}).values('id', 'id_plus_one'),
+ Book.objects.extra(select={'id_plus_one': 'id + 1'}).values('id', 'id_plus_one'),
[
- {'id': self.a5.id, 'id_plus_one': self.a5.id + 1},
- {'id': self.a6.id, 'id_plus_one': self.a6.id + 1},
- {'id': self.a4.id, 'id_plus_one': self.a4.id + 1},
- {'id': self.a2.id, 'id_plus_one': self.a2.id + 1},
- {'id': self.a3.id, 'id_plus_one': self.a3.id + 1},
- {'id': self.a7.id, 'id_plus_one': self.a7.id + 1},
- {'id': self.a1.id, 'id_plus_one': self.a1.id + 1},
+ {'id': self.b5.id, 'id_plus_one': self.b5.id + 1},
+ {'id': self.b6.id, 'id_plus_one': self.b6.id + 1},
+ {'id': self.b4.id, 'id_plus_one': self.b4.id + 1},
+ {'id': self.b2.id, 'id_plus_one': self.b2.id + 1},
+ {'id': self.b3.id, 'id_plus_one': self.b3.id + 1},
+ {'id': self.b7.id, 'id_plus_one': self.b7.id + 1},
+ {'id': self.b1.id, 'id_plus_one': self.b1.id + 1},
],
transform=identity)
data = {
@@ -189,66 +191,67 @@ def test_values(self):
'id_plus_eight': 'id+8',
}
self.assertQuerysetEqual(
- Article.objects.filter(id=self.a1.id).extra(select=data).values(*data.keys()),
+ Book.objects.filter(id=self.b1.id).extra(select=data).values(*data.keys()),
[{
- 'id_plus_one': self.a1.id + 1,
- 'id_plus_two': self.a1.id + 2,
- 'id_plus_three': self.a1.id + 3,
- 'id_plus_four': self.a1.id + 4,
- 'id_plus_five': self.a1.id + 5,
- 'id_plus_six': self.a1.id + 6,
- 'id_plus_seven': self.a1.id + 7,
- 'id_plus_eight': self.a1.id + 8,
+ 'id_plus_one': self.b1.id + 1,
+ 'id_plus_two': self.b1.id + 2,
+ 'id_plus_three': self.b1.id + 3,
+ 'id_plus_four': self.b1.id + 4,
+ 'id_plus_five': self.b1.id + 5,
+ 'id_plus_six': self.b1.id + 6,
+ 'id_plus_seven': self.b1.id + 7,
+ 'id_plus_eight': self.b1.id + 8,
}], transform=identity)
# You can specify fields from forward and reverse relations, just like filter().
self.assertQuerysetEqual(
- Article.objects.values('headline', 'author__name'),
+ Book.objects.values('name', 'author__name'),
[
- {'headline': self.a5.headline, 'author__name': self.au2.name},
- {'headline': self.a6.headline, 'author__name': self.au2.name},
- {'headline': self.a4.headline, 'author__name': self.au1.name},
- {'headline': self.a2.headline, 'author__name': self.au1.name},
- {'headline': self.a3.headline, 'author__name': self.au1.name},
- {'headline': self.a7.headline, 'author__name': self.au2.name},
- {'headline': self.a1.headline, 'author__name': self.au1.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},
], transform=identity)
self.assertQuerysetEqual(
- Author.objects.values('name', 'article__headline').order_by('name', 'article__headline'),
+ Author.objects.values('name', 'book__name').order_by('name', 'book__name'),
[
- {'name': self.au1.name, 'article__headline': self.a1.headline},
- {'name': self.au1.name, 'article__headline': self.a2.headline},
- {'name': self.au1.name, 'article__headline': self.a3.headline},
- {'name': self.au1.name, 'article__headline': self.a4.headline},
- {'name': self.au2.name, 'article__headline': self.a5.headline},
- {'name': self.au2.name, 'article__headline': self.a6.headline},
- {'name': self.au2.name, 'article__headline': self.a7.headline},
+ {'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},
], transform=identity)
self.assertQuerysetEqual(
- Author.objects.values('name', 'article__headline', 'article__tag__name').order_by('name', 'article__headline', 'article__tag__name'),
+ Author.objects.values('name', 'book__name', 'book__tag__name').order_by('name', 'book__name', 'book__tag__name'),
[
- {'name': self.au1.name, 'article__headline': self.a1.headline, 'article__tag__name': self.t1.name},
- {'name': self.au1.name, 'article__headline': self.a2.headline, 'article__tag__name': self.t1.name},
- {'name': self.au1.name, 'article__headline': self.a3.headline, 'article__tag__name': self.t1.name},
- {'name': self.au1.name, 'article__headline': self.a3.headline, 'article__tag__name': self.t2.name},
- {'name': self.au1.name, 'article__headline': self.a4.headline, 'article__tag__name': self.t2.name},
- {'name': self.au2.name, 'article__headline': self.a5.headline, 'article__tag__name': self.t2.name},
- {'name': self.au2.name, 'article__headline': self.a5.headline, 'article__tag__name': self.t3.name},
- {'name': self.au2.name, 'article__headline': self.a6.headline, 'article__tag__name': self.t3.name},
- {'name': self.au2.name, 'article__headline': self.a7.headline, 'article__tag__name': self.t3.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},
], 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
# model nor in extra(select)).
self.assertRaises(FieldError,
- Article.objects.extra(select={'id_plus_one': 'id + 1'}).values,
+ Book.objects.extra(select={'id_plus_one': 'id + 1'}).values,
'id', 'id_plus_two')
# If you don't specify field names to values(), all are returned.
- self.assertQuerysetEqual(Article.objects.filter(id=self.a5.id).values(),
+ self.assertQuerysetEqual(Book.objects.filter(id=self.b5.id).values(),
[{
- 'id': self.a5.id,
+ 'id': self.b5.id,
'author_id': self.au2.id,
- 'headline': 'Article 5',
- 'pub_date': datetime(2005, 8, 1, 9, 0)
+ 'name': 'Book 5',
+ 'pages': 0,
+ 'pubdate': datetime(2005, 8, 1, 9, 0)
}], transform=identity)
def test_values_list(self):
@@ -257,358 +260,358 @@ def test_values_list(self):
# 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(Article.objects.values_list('headline'),
+ self.assertQuerysetEqual(Book.objects.values_list('name'),
[
- ('Article 5',),
- ('Article 6',),
- ('Article 4',),
- ('Article 2',),
- ('Article 3',),
- ('Article 7',),
- ('Article 1',),
+ ('Book 5',),
+ ('Book 6',),
+ ('Book 4',),
+ ('Book 2',),
+ ('Book 3',),
+ ('Book 7',),
+ ('Book 1',),
], transform=identity)
- self.assertQuerysetEqual(Article.objects.values_list('id').order_by('id'),
- [(self.a1.id,), (self.a2.id,), (self.a3.id,), (self.a4.id,), (self.a5.id,), (self.a6.id,), (self.a7.id,)],
+ self.assertQuerysetEqual(Book.objects.values_list('id').order_by('id'),
+ [(self.b1.id,), (self.b2.id,), (self.b3.id,), (self.b4.id,), (self.b5.id,), (self.b6.id,), (self.b7.id,)],
transform=identity)
self.assertQuerysetEqual(
- Article.objects.values_list('id', flat=True).order_by('id'),
- [self.a1.id, self.a2.id, self.a3.id, self.a4.id, self.a5.id, self.a6.id, self.a7.id],
+ Book.objects.values_list('id', flat=True).order_by('id'),
+ [self.b1.id, self.b2.id, self.b3.id, self.b4.id, self.b5.id, self.b6.id, self.b7.id],
transform=identity)
self.assertQuerysetEqual(
- Article.objects.extra(select={'id_plus_one': 'id+1'})
+ Book.objects.extra(select={'id_plus_one': 'id+1'})
.order_by('id').values_list('id'),
- [(self.a1.id,), (self.a2.id,), (self.a3.id,), (self.a4.id,), (self.a5.id,), (self.a6.id,), (self.a7.id,)],
+ [(self.b1.id,), (self.b2.id,), (self.b3.id,), (self.b4.id,), (self.b5.id,), (self.b6.id,), (self.b7.id,)],
transform=identity)
self.assertQuerysetEqual(
- Article.objects.extra(select={'id_plus_one': 'id+1'})
+ Book.objects.extra(select={'id_plus_one': 'id+1'})
.order_by('id').values_list('id_plus_one', 'id'),
[
- (self.a1.id+1, self.a1.id),
- (self.a2.id+1, self.a2.id),
- (self.a3.id+1, self.a3.id),
- (self.a4.id+1, self.a4.id),
- (self.a5.id+1, self.a5.id),
- (self.a6.id+1, self.a6.id),
- (self.a7.id+1, self.a7.id)
+ (self.b1.id+1, self.b1.id),
+ (self.b2.id+1, self.b2.id),
+ (self.b3.id+1, self.b3.id),
+ (self.b4.id+1, self.b4.id),
+ (self.b5.id+1, self.b5.id),
+ (self.b6.id+1, self.b6.id),
+ (self.b7.id+1, self.b7.id)
],
transform=identity)
self.assertQuerysetEqual(
- Article.objects.extra(select={'id_plus_one': 'id+1'})
+ Book.objects.extra(select={'id_plus_one': 'id+1'})
.order_by('id').values_list('id', 'id_plus_one'),
[
- (self.a1.id, self.a1.id+1),
- (self.a2.id, self.a2.id+1),
- (self.a3.id, self.a3.id+1),
- (self.a4.id, self.a4.id+1),
- (self.a5.id, self.a5.id+1),
- (self.a6.id, self.a6.id+1),
- (self.a7.id, self.a7.id+1)
+ (self.b1.id, self.b1.id+1),
+ (self.b2.id, self.b2.id+1),
+ (self.b3.id, self.b3.id+1),
+ (self.b4.id, self.b4.id+1),
+ (self.b5.id, self.b5.id+1),
+ (self.b6.id, self.b6.id+1),
+ (self.b7.id, self.b7.id+1)
],
transform=identity)
self.assertQuerysetEqual(
- Author.objects.values_list('name', 'article__headline', 'article__tag__name').order_by('name', 'article__headline', 'article__tag__name'),
+ Author.objects.values_list('name', 'book__name', 'book__tag__name').order_by('name', 'book__name', 'book__tag__name'),
[
- (self.au1.name, self.a1.headline, self.t1.name),
- (self.au1.name, self.a2.headline, self.t1.name),
- (self.au1.name, self.a3.headline, self.t1.name),
- (self.au1.name, self.a3.headline, self.t2.name),
- (self.au1.name, self.a4.headline, self.t2.name),
- (self.au2.name, self.a5.headline, self.t2.name),
- (self.au2.name, self.a5.headline, self.t3.name),
- (self.au2.name, self.a6.headline, self.t3.name),
- (self.au2.name, self.a7.headline, self.t3.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),
], transform=identity)
- self.assertRaises(TypeError, Article.objects.values_list, 'id', 'headline', flat=True)
+ self.assertRaises(TypeError, Book.objects.values_list, 'id', 'name', flat=True)
def test_get_next_previous_by(self):
# Every DateField and DateTimeField creates get_next_by_FOO() and
# get_previous_by_FOO() methods. In the case of identical date values,
# these methods will use the ID as a fallback check. This guarantees
# that no records are skipped or duplicated.
- self.assertEqual(repr(self.a1.get_next_by_pub_date()),
- '<Article: Article 2>')
- self.assertEqual(repr(self.a2.get_next_by_pub_date()),
- '<Article: Article 3>')
- self.assertEqual(repr(self.a2.get_next_by_pub_date(headline__endswith='6')),
- '<Article: Article 6>')
- self.assertEqual(repr(self.a3.get_next_by_pub_date()),
- '<Article: Article 7>')
- self.assertEqual(repr(self.a4.get_next_by_pub_date()),
- '<Article: Article 6>')
- self.assertRaises(Article.DoesNotExist, self.a5.get_next_by_pub_date)
- self.assertEqual(repr(self.a6.get_next_by_pub_date()),
- '<Article: Article 5>')
- self.assertEqual(repr(self.a7.get_next_by_pub_date()),
- '<Article: Article 4>')
-
- self.assertEqual(repr(self.a7.get_previous_by_pub_date()),
- '<Article: Article 3>')
- self.assertEqual(repr(self.a6.get_previous_by_pub_date()),
- '<Article: Article 4>')
- self.assertEqual(repr(self.a5.get_previous_by_pub_date()),
- '<Article: Article 6>')
- self.assertEqual(repr(self.a4.get_previous_by_pub_date()),
- '<Article: Article 7>')
- self.assertEqual(repr(self.a3.get_previous_by_pub_date()),
- '<Article: Article 2>')
- self.assertEqual(repr(self.a2.get_previous_by_pub_date()),
- '<Article: Article 1>')
+ self.assertEqual(repr(self.b1.get_next_by_pubdate()),
+ '<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')),
+ '<Book: Book 6>')
+ self.assertEqual(repr(self.b3.get_next_by_pubdate()),
+ '<Book: Book 7>')
+ self.assertEqual(repr(self.b4.get_next_by_pubdate()),
+ '<Book: Book 6>')
+ self.assertRaises(Book.DoesNotExist, self.b5.get_next_by_pubdate)
+ self.assertEqual(repr(self.b6.get_next_by_pubdate()),
+ '<Book: Book 5>')
+ self.assertEqual(repr(self.b7.get_next_by_pubdate()),
+ '<Book: Book 4>')
+
+ self.assertEqual(repr(self.b7.get_previous_by_pubdate()),
+ '<Book: Book 3>')
+ self.assertEqual(repr(self.b6.get_previous_by_pubdate()),
+ '<Book: Book 4>')
+ self.assertEqual(repr(self.b5.get_previous_by_pubdate()),
+ '<Book: Book 6>')
+ self.assertEqual(repr(self.b4.get_previous_by_pubdate()),
+ '<Book: Book 7>')
+ self.assertEqual(repr(self.b3.get_previous_by_pubdate()),
+ '<Book: Book 2>')
+ self.assertEqual(repr(self.b2.get_previous_by_pubdate()),
+ '<Book: Book 1>')
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.
- a8 = Article(headline='Article_ with underscore', pub_date=datetime(2005, 11, 20))
- a8.save()
- self.assertQuerysetEqual(Article.objects.filter(headline__startswith='Article'),
+ b8 = Book(name='Book_ with underscore', pubdate=datetime(2005, 11, 20))
+ b8.save()
+ self.assertQuerysetEqual(Book.objects.filter(name__startswith='Book'),
[
- '<Article: Article_ with underscore>',
- '<Article: Article 5>',
- '<Article: Article 6>',
- '<Article: Article 4>',
- '<Article: Article 2>',
- '<Article: Article 3>',
- '<Article: Article 7>',
- '<Article: Article 1>',
+ '<Book: Book_ with underscore>',
+ '<Book: Book 5>',
+ '<Book: Book 6>',
+ '<Book: Book 4>',
+ '<Book: Book 2>',
+ '<Book: Book 3>',
+ '<Book: Book 7>',
+ '<Book: Book 1>',
])
- self.assertQuerysetEqual(Article.objects.filter(headline__startswith='Article_'),
- ['<Article: Article_ with underscore>'])
- a9 = Article(headline='Article% with percent sign', pub_date=datetime(2005, 11, 21))
- a9.save()
- self.assertQuerysetEqual(Article.objects.filter(headline__startswith='Article'),
+ self.assertQuerysetEqual(Book.objects.filter(name__startswith='Book_'),
+ ['<Book: Book_ with underscore>'])
+ b9 = Book(name='Book% with percent sign', pubdate=datetime(2005, 11, 21))
+ b9.save()
+ self.assertQuerysetEqual(Book.objects.filter(name__startswith='Book'),
[
- '<Article: Article% with percent sign>',
- '<Article: Article_ with underscore>',
- '<Article: Article 5>',
- '<Article: Article 6>',
- '<Article: Article 4>',
- '<Article: Article 2>',
- '<Article: Article 3>',
- '<Article: Article 7>',
- '<Article: Article 1>',
+ '<Book: Book% with percent sign>',
+ '<Book: Book_ with underscore>',
+ '<Book: Book 5>',
+ '<Book: Book 6>',
+ '<Book: Book 4>',
+ '<Book: Book 2>',
+ '<Book: Book 3>',
+ '<Book: Book 7>',
+ '<Book: Book 1>',
])
- self.assertQuerysetEqual(Article.objects.filter(headline__startswith='Article%'),
- ['<Article: Article% with percent sign>'])
- a10 = Article(headline='Article with \\ backslash', pub_date=datetime(2005, 11, 22))
- a10.save()
- self.assertQuerysetEqual(Article.objects.filter(headline__contains='\\'),
- ['<Article: Article with \ backslash>'])
+ self.assertQuerysetEqual(Book.objects.filter(name__startswith='Book%'),
+ ['<Book: Book% with percent sign>'])
+ b10 = Book(name='Book with \\ backslash', pubdate=datetime(2005, 11, 22))
+ b10.save()
+ self.assertQuerysetEqual(Book.objects.filter(name__contains='\\'),
+ ['<Book: Book with \ backslash>'])
def test_exclude(self):
- a8 = Article.objects.create(headline='Article_ with underscore', pub_date=datetime(2005, 11, 20))
- a9 = Article.objects.create(headline='Article% with percent sign', pub_date=datetime(2005, 11, 21))
- a10 = Article.objects.create(headline='Article with \\ backslash', pub_date=datetime(2005, 11, 22))
+ 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))
# exclude() is the opposite of filter() when doing lookups:
self.assertQuerysetEqual(
- Article.objects.filter(headline__contains='Article').exclude(headline__contains='with'),
+ Book.objects.filter(name__contains='Book').exclude(name__contains='with'),
[
- '<Article: Article 5>',
- '<Article: Article 6>',
- '<Article: Article 4>',
- '<Article: Article 2>',
- '<Article: Article 3>',
- '<Article: Article 7>',
- '<Article: Article 1>',
+ '<Book: Book 5>',
+ '<Book: Book 6>',
+ '<Book: Book 4>',
+ '<Book: Book 2>',
+ '<Book: Book 3>',
+ '<Book: Book 7>',
+ '<Book: Book 1>',
])
- self.assertQuerysetEqual(Article.objects.exclude(headline__startswith="Article_"),
+ self.assertQuerysetEqual(Book.objects.exclude(name__startswith="Book_"),
[
- '<Article: Article with \\ backslash>',
- '<Article: Article% with percent sign>',
- '<Article: Article 5>',
- '<Article: Article 6>',
- '<Article: Article 4>',
- '<Article: Article 2>',
- '<Article: Article 3>',
- '<Article: Article 7>',
- '<Article: Article 1>',
+ '<Book: Book with \\ backslash>',
+ '<Book: Book% with percent sign>',
+ '<Book: Book 5>',
+ '<Book: Book 6>',
+ '<Book: Book 4>',
+ '<Book: Book 2>',
+ '<Book: Book 3>',
+ '<Book: Book 7>',
+ '<Book: Book 1>',
])
- self.assertQuerysetEqual(Article.objects.exclude(headline="Article 7"),
+ self.assertQuerysetEqual(Book.objects.exclude(name="Book 7"),
[
- '<Article: Article with \\ backslash>',
- '<Article: Article% with percent sign>',
- '<Article: Article_ with underscore>',
- '<Article: Article 5>',
- '<Article: Article 6>',
- '<Article: Article 4>',
- '<Article: Article 2>',
- '<Article: Article 3>',
- '<Article: Article 1>',
+ '<Book: Book with \\ backslash>',
+ '<Book: Book% with percent sign>',
+ '<Book: Book_ with underscore>',
+ '<Book: Book 5>',
+ '<Book: Book 6>',
+ '<Book: Book 4>',
+ '<Book: Book 2>',
+ '<Book: Book 3>',
+ '<Book: Book 1>',
])
def test_none(self):
# none() returns a QuerySet that behaves like any other QuerySet object
- self.assertQuerysetEqual(Article.objects.none(), [])
+ self.assertQuerysetEqual(Book.objects.none(), [])
self.assertQuerysetEqual(
- Article.objects.none().filter(headline__startswith='Article'), [])
+ Book.objects.none().filter(name__startswith='Book'), [])
self.assertQuerysetEqual(
- Article.objects.filter(headline__startswith='Article').none(), [])
- self.assertEqual(Article.objects.none().count(), 0)
+ Book.objects.filter(name__startswith='Book').none(), [])
+ self.assertEqual(Book.objects.none().count(), 0)
self.assertEqual(
- Article.objects.none().update(headline="This should not take effect"), 0)
+ Book.objects.none().update(name="This should not take effect"), 0)
self.assertQuerysetEqual(
- [article for article in Article.objects.none().iterator()],
+ [article for article in Book.objects.none().iterator()],
[])
def test_in(self):
# using __in with an empty list should return an empty query set
- self.assertQuerysetEqual(Article.objects.filter(id__in=[]), [])
- self.assertQuerysetEqual(Article.objects.exclude(id__in=[]),
+ self.assertQuerysetEqual(Book.objects.filter(id__in=[]), [])
+ self.assertQuerysetEqual(Book.objects.exclude(id__in=[]),
[
- '<Article: Article 5>',
- '<Article: Article 6>',
- '<Article: Article 4>',
- '<Article: Article 2>',
- '<Article: Article 3>',
- '<Article: Article 7>',
- '<Article: Article 1>',
+ '<Book: Book 5>',
+ '<Book: Book 6>',
+ '<Book: Book 4>',
+ '<Book: Book 2>',
+ '<Book: Book 3>',
+ '<Book: Book 7>',
+ '<Book: Book 1>',
])
def test_error_messages(self):
# Programming errors are pointed out with nice error messages
try:
- Article.objects.filter(pub_date_year='2005').count()
+ Book.objects.filter(pubdate_year='2005').count()
self.fail('FieldError not raised')
except FieldError as ex:
- self.assertEqual(str(ex), "Cannot resolve keyword 'pub_date_year' "
- "into field. Choices are: author, headline, id, pub_date, tag")
+ self.assertEqual(str(ex), "Cannot resolve keyword 'pubdate_year' "
+ "into field. Choices are: author, id, name, pages, pubdate, tag, tags")
try:
- Article.objects.filter(headline__starts='Article')
+ Book.objects.filter(name__starts='Book')
self.fail('FieldError not raised')
except FieldError as ex:
- self.assertEqual(str(ex), "Join on field 'headline' not permitted. "
+ self.assertEqual(str(ex), "Join on field 'name' not permitted. "
"Did you misspell 'starts' for the lookup type?")
def test_regex(self):
- # Create some articles with a bit more interesting headlines for testing field lookups:
- for a in Article.objects.all():
+ # Create some articles with a bit more interesting names for testing field lookups:
+ for a in Book.objects.all():
a.delete()
now = datetime.now()
- a1 = Article(pub_date=now, headline='f')
- a1.save()
- a2 = Article(pub_date=now, headline='fo')
- a2.save()
- a3 = Article(pub_date=now, headline='foo')
- a3.save()
- a4 = Article(pub_date=now, headline='fooo')
- a4.save()
- a5 = Article(pub_date=now, headline='hey-Foo')
- a5.save()
- a6 = Article(pub_date=now, headline='bar')
- a6.save()
- a7 = Article(pub_date=now, headline='AbBa')
- a7.save()
- a8 = Article(pub_date=now, headline='baz')
- a8.save()
- a9 = Article(pub_date=now, headline='baxZ')
- a9.save()
+ b1 = Book(pubdate=now, name='f')
+ b1.save()
+ b2 = Book(pubdate=now, name='fo')
+ b2.save()
+ b3 = Book(pubdate=now, name='foo')
+ b3.save()
+ b4 = Book(pubdate=now, name='fooo')
+ b4.save()
+ b5 = Book(pubdate=now, name='hey-Foo')
+ b5.save()
+ b6 = Book(pubdate=now, name='bar')
+ b6.save()
+ b7 = Book(pubdate=now, name='AbBa')
+ b7.save()
+ b8 = Book(pubdate=now, name='baz')
+ b8.save()
+ b9 = Book(pubdate=now, name='baxZ')
+ b9.save()
# zero-or-more
- self.assertQuerysetEqual(Article.objects.filter(headline__regex=r'fo*'),
- ['<Article: f>', '<Article: fo>', '<Article: foo>', '<Article: fooo>'])
- self.assertQuerysetEqual(Article.objects.filter(headline__iregex=r'fo*'),
+ self.assertQuerysetEqual(Book.objects.filter(name__regex=r'fo*'),
+ ['<Book: f>', '<Book: fo>', '<Book: foo>', '<Book: fooo>'])
+ self.assertQuerysetEqual(Book.objects.filter(name__iregex=r'fo*'),
[
- '<Article: f>',
- '<Article: fo>',
- '<Article: foo>',
- '<Article: fooo>',
- '<Article: hey-Foo>',
+ '<Book: f>',
+ '<Book: fo>',
+ '<Book: foo>',
+ '<Book: fooo>',
+ '<Book: hey-Foo>',
])
# one-or-more
- self.assertQuerysetEqual(Article.objects.filter(headline__regex=r'fo+'),
- ['<Article: fo>', '<Article: foo>', '<Article: fooo>'])
+ self.assertQuerysetEqual(Book.objects.filter(name__regex=r'fo+'),
+ ['<Book: fo>', '<Book: foo>', '<Book: fooo>'])
# wildcard
- self.assertQuerysetEqual(Article.objects.filter(headline__regex=r'fooo?'),
- ['<Article: foo>', '<Article: fooo>'])
+ self.assertQuerysetEqual(Book.objects.filter(name__regex=r'fooo?'),
+ ['<Book: foo>', '<Book: fooo>'])
# leading anchor
- self.assertQuerysetEqual(Article.objects.filter(headline__regex=r'^b'),
- ['<Article: bar>', '<Article: baxZ>', '<Article: baz>'])
- self.assertQuerysetEqual(Article.objects.filter(headline__iregex=r'^a'),
- ['<Article: AbBa>'])
+ self.assertQuerysetEqual(Book.objects.filter(name__regex=r'^b'),
+ ['<Book: bar>', '<Book: baxZ>', '<Book: baz>'])
+ self.assertQuerysetEqual(Book.objects.filter(name__iregex=r'^a'),
+ ['<Book: AbBa>'])
# trailing anchor
- self.assertQuerysetEqual(Article.objects.filter(headline__regex=r'z$'),
- ['<Article: baz>'])
- self.assertQuerysetEqual(Article.objects.filter(headline__iregex=r'z$'),
- ['<Article: baxZ>', '<Article: baz>'])
+ self.assertQuerysetEqual(Book.objects.filter(name__regex=r'z$'),
+ ['<Book: baz>'])
+ self.assertQuerysetEqual(Book.objects.filter(name__iregex=r'z$'),
+ ['<Book: baxZ>', '<Book: baz>'])
# character sets
- self.assertQuerysetEqual(Article.objects.filter(headline__regex=r'ba[rz]'),
- ['<Article: bar>', '<Article: baz>'])
- self.assertQuerysetEqual(Article.objects.filter(headline__regex=r'ba.[RxZ]'),
- ['<Article: baxZ>'])
- self.assertQuerysetEqual(Article.objects.filter(headline__iregex=r'ba[RxZ]'),
- ['<Article: bar>', '<Article: baxZ>', '<Article: baz>'])
+ self.assertQuerysetEqual(Book.objects.filter(name__regex=r'ba[rz]'),
+ ['<Book: bar>', '<Book: baz>'])
+ self.assertQuerysetEqual(Book.objects.filter(name__regex=r'ba.[RxZ]'),
+ ['<Book: baxZ>'])
+ self.assertQuerysetEqual(Book.objects.filter(name__iregex=r'ba[RxZ]'),
+ ['<Book: bar>', '<Book: baxZ>', '<Book: baz>'])
# and more articles:
- a10 = Article(pub_date=now, headline='foobar')
- a10.save()
- a11 = Article(pub_date=now, headline='foobaz')
- a11.save()
- a12 = Article(pub_date=now, headline='ooF')
- a12.save()
- a13 = Article(pub_date=now, headline='foobarbaz')
- a13.save()
- a14 = Article(pub_date=now, headline='zoocarfaz')
- a14.save()
- a15 = Article(pub_date=now, headline='barfoobaz')
- a15.save()
- a16 = Article(pub_date=now, headline='bazbaRFOO')
- a16.save()
+ b10 = Book(pubdate=now, name='foobar')
+ b10.save()
+ b11 = Book(pubdate=now, name='foobaz')
+ b11.save()
+ b12 = Book(pubdate=now, name='ooF')
+ b12.save()
+ b13 = Book(pubdate=now, name='foobarbaz')
+ b13.save()
+ b14 = Book(pubdate=now, name='zoocarfaz')
+ b14.save()
+ b15 = Book(pubdate=now, name='barfoobaz')
+ b15.save()
+ b16 = Book(pubdate=now, name='bazbaRFOO')
+ b16.save()
# alternation
- self.assertQuerysetEqual(Article.objects.filter(headline__regex=r'oo(f|b)'),
+ self.assertQuerysetEqual(Book.objects.filter(name__regex=r'oo(f|b)'),
[
- '<Article: barfoobaz>',
- '<Article: foobar>',
- '<Article: foobarbaz>',
- '<Article: foobaz>',
+ '<Book: barfoobaz>',
+ '<Book: foobar>',
+ '<Book: foobarbaz>',
+ '<Book: foobaz>',
])
- self.assertQuerysetEqual(Article.objects.filter(headline__iregex=r'oo(f|b)'),
+ self.assertQuerysetEqual(Book.objects.filter(name__iregex=r'oo(f|b)'),
[
- '<Article: barfoobaz>',
- '<Article: foobar>',
- '<Article: foobarbaz>',
- '<Article: foobaz>',
- '<Article: ooF>',
+ '<Book: barfoobaz>',
+ '<Book: foobar>',
+ '<Book: foobarbaz>',
+ '<Book: foobaz>',
+ '<Book: ooF>',
])
- self.assertQuerysetEqual(Article.objects.filter(headline__regex=r'^foo(f|b)'),
- ['<Article: foobar>', '<Article: foobarbaz>', '<Article: foobaz>'])
+ self.assertQuerysetEqual(Book.objects.filter(name__regex=r'^foo(f|b)'),
+ ['<Book: foobar>', '<Book: foobarbaz>', '<Book: foobaz>'])
# greedy matching
- self.assertQuerysetEqual(Article.objects.filter(headline__regex=r'b.*az'),
+ self.assertQuerysetEqual(Book.objects.filter(name__regex=r'b.*az'),
[
- '<Article: barfoobaz>',
- '<Article: baz>',
- '<Article: bazbaRFOO>',
- '<Article: foobarbaz>',
- '<Article: foobaz>',
+ '<Book: barfoobaz>',
+ '<Book: baz>',
+ '<Book: bazbaRFOO>',
+ '<Book: foobarbaz>',
+ '<Book: foobaz>',
])
- self.assertQuerysetEqual(Article.objects.filter(headline__iregex=r'b.*ar'),
+ self.assertQuerysetEqual(Book.objects.filter(name__iregex=r'b.*ar'),
[
- '<Article: bar>',
- '<Article: barfoobaz>',
- '<Article: bazbaRFOO>',
- '<Article: foobar>',
- '<Article: foobarbaz>',
+ '<Book: bar>',
+ '<Book: barfoobaz>',
+ '<Book: bazbaRFOO>',
+ '<Book: foobar>',
+ '<Book: foobarbaz>',
])
@skipUnlessDBFeature('supports_regex_backreferencing')
def test_regex_backreferencing(self):
# grouping and backreferences
now = datetime.now()
- a10 = Article(pub_date=now, headline='foobar')
- a10.save()
- a11 = Article(pub_date=now, headline='foobaz')
- a11.save()
- a12 = Article(pub_date=now, headline='ooF')
- a12.save()
- a13 = Article(pub_date=now, headline='foobarbaz')
- a13.save()
- a14 = Article(pub_date=now, headline='zoocarfaz')
- a14.save()
- a15 = Article(pub_date=now, headline='barfoobaz')
- a15.save()
- a16 = Article(pub_date=now, headline='bazbaRFOO')
- a16.save()
- self.assertQuerysetEqual(Article.objects.filter(headline__regex=r'b(.).*b\1'),
- ['<Article: barfoobaz>', '<Article: bazbaRFOO>', '<Article: foobarbaz>'])
+ b10 = Book(pubdate=now, name='foobar')
+ b10.save()
+ b11 = Book(pubdate=now, name='foobaz')
+ b11.save()
+ b12 = Book(pubdate=now, name='ooF')
+ b12.save()
+ b13 = Book(pubdate=now, name='foobarbaz')
+ b13.save()
+ b14 = Book(pubdate=now, name='zoocarfaz')
+ b14.save()
+ b15 = Book(pubdate=now, name='barfoobaz')
+ b15.save()
+ b16 = Book(pubdate=now, name='bazbaRFOO')
+ b16.save()
+ self.assertQuerysetEqual(Book.objects.filter(name__regex=r'b(.).*b\1'),
+ ['<Book: barfoobaz>', '<Book: bazbaRFOO>', '<Book: foobarbaz>'])
def test_nonfield_lookups(self):
"""
@@ -616,11 +619,11 @@ def test_nonfield_lookups(self):
exception.
"""
with self.assertRaises(FieldError):
- Article.objects.filter(headline__blahblah=99)
+ Book.objects.filter(name__blahblah=99)
with self.assertRaises(FieldError):
- Article.objects.filter(headline__blahblah__exact=99)
+ Book.objects.filter(name__blahblah__exact=99)
with self.assertRaises(FieldError):
- Article.objects.filter(blahblah=99)
+ Book.objects.filter(blahblah=99)
def test_lookup_collision(self):
"""
View
1  tests/runtests.py
@@ -21,6 +21,7 @@
SUBDIRS_TO_SKIP = ['templates']
ALWAYS_INSTALLED_APPS = [
+ 'shared_models',
'django.contrib.contenttypes',
'django.contrib.auth',
'django.contrib.sites',
View
0  tests/shared_models/__init__.py
No changes.
View
30 tests/shared_models/models.py
@@ -0,0 +1,30 @@
+from django.db import models
+from django.utils import timezone
+from django.utils.encoding import python_2_unicode_compatible
+
+
+class Tag(models.Model):
+ name = models.CharField(max_length=255)
+
+
+@python_2_unicode_compatible
+class Author(models.Model):
+ name = models.CharField(max_length=100)
+
+ def __str__(self):
+ return self.name
+
+
+@python_2_unicode_compatible
+class Book(models.Model):
+ name = models.CharField(max_length=200)
+ pages = models.IntegerField(default=0)
+ author = models.ForeignKey(Author, null=True)
+ pubdate = models.DateTimeField()
+ tags = models.ManyToManyField(Tag)
+
+ class Meta:
+ ordering = ['-pubdate', 'name']
+
+ def __str__(self):
+ return self.name
View
18 tests/signals_regress/models.py
@@ -1,18 +0,0 @@
-from django.db import models
-from django.utils.encoding import python_2_unicode_compatible
-
-
-@python_2_unicode_compatible
-class Author(models.Model):
- name = models.CharField(max_length=20)
-
- def __str__(self):
- return self.name
-
-@python_2_unicode_compatible
-class Book(models.Model):
- name = models.CharField(max_length=20)
- authors = models.ManyToManyField(Author)
-
- def __str__(self):
- return self.name
View
6 tests/signals_regress/tests.py
@@ -3,7 +3,7 @@
from django.db import models
from django.test import TestCase
-from .models import Author, Book
+from shared_models.models import Author, Book
class SignalsRegressTests(TestCase):
@@ -77,7 +77,7 @@ def test_model_signals(self):
"Is created"
])
- b1 = Book(name='Snow Crash')
+ b1 = Book(name='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 @@ def test_model_signals(self):
def test_m2m_signals(self):
""" Assigning and removing to/from m2m shouldn't generate an m2m signal """
- b1 = Book(name='Snow Crash')
+ b1 = Book(name='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)
View
5 tests/urlpatterns_reverse/tests.py
@@ -183,6 +183,11 @@ def test_prefix_format_char(self):
self.assertEqual('/bump%2520map/includes/non_path_include/',
reverse('non_path_include', prefix='/bump%20map/'))
+ def test_non_urlsafe_prefix_with_args(self):
+ # Regression for #20022
+ self.assertEqual('/%7Eme/places/1/',
+ reverse('places', args=[1], prefix='/~me/'))
+
class ResolverTests(unittest.TestCase):
def test_resolver_repr(self):
"""

0 comments on commit 1059da8

Please sign in to comment.
Something went wrong with that request. Please try again.