diff options
| author | Brian King <brian@liip.ch> | 2015-06-05 12:40:51 +0100 |
|---|---|---|
| committer | Tim Graham <timograham@gmail.com> | 2015-06-15 09:37:38 -0400 |
| commit | bfb5b7150ff52571a7a3cf10e0dd0d1dbd45c4b5 (patch) | |
| tree | 6ad940d20c235e2647e8188c608c061a8770bba0 /tests | |
| parent | 841a87785a78cc37362a66856025bae2f7ba633c (diff) | |
Fixed #24912 -- Fixed prefetch_related failure for UUIDField primary keys
This resolves a problem on databases besides PostgreSQL when using
prefetch_related with a source model that uses a UUID primary key.
Diffstat (limited to 'tests')
| -rw-r--r-- | tests/prefetch_related/models.py | 17 | ||||
| -rw-r--r-- | tests/prefetch_related/test_uuid.py | 95 |
2 files changed, 112 insertions, 0 deletions
diff --git a/tests/prefetch_related/models.py b/tests/prefetch_related/models.py index bfc0ae0217..207f12a11a 100644 --- a/tests/prefetch_related/models.py +++ b/tests/prefetch_related/models.py @@ -1,3 +1,5 @@ +import uuid + from django.contrib.contenttypes.fields import ( GenericForeignKey, GenericRelation, ) @@ -257,3 +259,18 @@ class Author2(models.Model): class Meta: ordering = ['id'] + + +# Models for many-to-many with UUID pk test: + +class Pet(models.Model): + id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False) + name = models.CharField(max_length=20) + people = models.ManyToManyField(Person, related_name='pets') + + +class Flea(models.Model): + id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False) + current_room = models.ForeignKey(Room, related_name='fleas', null=True) + pets_visited = models.ManyToManyField(Pet, related_name='fleas_hosted') + people_visited = models.ManyToManyField(Person, related_name='fleas_hosted') diff --git a/tests/prefetch_related/test_uuid.py b/tests/prefetch_related/test_uuid.py new file mode 100644 index 0000000000..8d885e1057 --- /dev/null +++ b/tests/prefetch_related/test_uuid.py @@ -0,0 +1,95 @@ +from __future__ import unicode_literals + +from django.test import TestCase + +from .models import Flea, House, Person, Pet, Room + + +class UUIDPrefetchRelated(TestCase): + + def test_prefetch_related_from_uuid_model(self): + Pet.objects.create(name='Fifi').people.add( + Person.objects.create(name='Ellen'), + Person.objects.create(name='George'), + ) + + with self.assertNumQueries(2): + pet = Pet.objects.prefetch_related('people').get(name='Fifi') + with self.assertNumQueries(0): + self.assertEqual(2, len(pet.people.all())) + + def test_prefetch_related_to_uuid_model(self): + Person.objects.create(name='Bella').pets.add( + Pet.objects.create(name='Socks'), + Pet.objects.create(name='Coffee'), + ) + + with self.assertNumQueries(2): + person = Person.objects.prefetch_related('pets').get(name='Bella') + with self.assertNumQueries(0): + self.assertEqual(2, len(person.pets.all())) + + def test_prefetch_related_from_uuid_model_to_uuid_model(self): + fleas = [Flea.objects.create() for i in range(3)] + Pet.objects.create(name='Fifi').fleas_hosted.add(*fleas) + Pet.objects.create(name='Bobo').fleas_hosted.add(*fleas) + + with self.assertNumQueries(2): + pet = Pet.objects.prefetch_related('fleas_hosted').get(name='Fifi') + with self.assertNumQueries(0): + self.assertEqual(3, len(pet.fleas_hosted.all())) + + with self.assertNumQueries(2): + flea = Flea.objects.prefetch_related('pets_visited').get(pk=fleas[0].pk) + with self.assertNumQueries(0): + self.assertEqual(2, len(flea.pets_visited.all())) + + +class UUIDPrefetchRelatedLookups(TestCase): + + @classmethod + def setUpTestData(cls): + house = House.objects.create(name='Redwood', address='Arcata') + room = Room.objects.create(name='Racoon', house=house) + fleas = [Flea.objects.create(current_room=room) for i in range(3)] + pet = Pet.objects.create(name='Spooky') + pet.fleas_hosted.add(*fleas) + person = Person.objects.create(name='Bob') + person.houses.add(house) + person.pets.add(pet) + person.fleas_hosted.add(*fleas) + + def test_from_uuid_pk_lookup_uuid_pk_integer_pk(self): + # From uuid-pk model, prefetch <uuid-pk model>.<integer-pk model>: + with self.assertNumQueries(4): + spooky = Pet.objects.prefetch_related('fleas_hosted__current_room__house').get(name='Spooky') + with self.assertNumQueries(0): + self.assertEqual('Racoon', spooky.fleas_hosted.all()[0].current_room.name) + + def test_from_uuid_pk_lookup_integer_pk2_uuid_pk2(self): + # From uuid-pk model, prefetch <integer-pk model>.<integer-pk model>.<uuid-pk model>.<uuid-pk model>: + with self.assertNumQueries(5): + spooky = Pet.objects.prefetch_related('people__houses__rooms__fleas').get(name='Spooky') + with self.assertNumQueries(0): + self.assertEqual(3, len(spooky.people.all()[0].houses.all()[0].rooms.all()[0].fleas.all())) + + def test_from_integer_pk_lookup_uuid_pk_integer_pk(self): + # From integer-pk model, prefetch <uuid-pk model>.<integer-pk model>: + with self.assertNumQueries(3): + racoon = Room.objects.prefetch_related('fleas__people_visited').get(name='Racoon') + with self.assertNumQueries(0): + self.assertEqual('Bob', racoon.fleas.all()[0].people_visited.all()[0].name) + + def test_from_integer_pk_lookup_integer_pk_uuid_pk(self): + # From integer-pk model, prefetch <integer-pk model>.<uuid-pk model>: + with self.assertNumQueries(3): + redwood = House.objects.prefetch_related('rooms__fleas').get(name='Redwood') + with self.assertNumQueries(0): + self.assertEqual(3, len(redwood.rooms.all()[0].fleas.all())) + + def test_from_integer_pk_lookup_integer_pk_uuid_pk_uuid_pk(self): + # From integer-pk model, prefetch <integer-pk model>.<uuid-pk model>.<uuid-pk model>: + with self.assertNumQueries(4): + redwood = House.objects.prefetch_related('rooms__fleas__pets_visited').get(name='Redwood') + with self.assertNumQueries(0): + self.assertEqual('Spooky', redwood.rooms.all()[0].fleas.all()[0].pets_visited.all()[0].name) |
