diff options
author | Ran Benita <ran234@gmail.com> | 2017-10-17 11:28:00 +0800 |
---|---|---|
committer | Tim Graham <timograham@gmail.com> | 2017-10-28 20:33:42 -0400 |
commit | 03049fb8d96ccd1f1ed0285486103542de42faba (patch) | |
tree | 243c0b4cc9b622a47ce7a665d36d8b4ab4973a0d /tests/select_for_update | |
parent | 56b364bacca0d6a6cd8fbcd93aeb49f3ad46e58c (diff) | |
download | django-03049fb8d96ccd1f1ed0285486103542de42faba.tar.gz |
Refs #28010 -- Allowed reverse related fields in SELECT FOR UPDATE .. OF.
Thanks Adam Chidlow for polishing the patch.
Diffstat (limited to 'tests/select_for_update')
-rw-r--r-- | tests/select_for_update/models.py | 4 | ||||
-rw-r--r-- | tests/select_for_update/tests.py | 21 |
2 files changed, 22 insertions, 3 deletions
diff --git a/tests/select_for_update/models.py b/tests/select_for_update/models.py index b04ed31b00..b8154af3df 100644 --- a/tests/select_for_update/models.py +++ b/tests/select_for_update/models.py @@ -14,3 +14,7 @@ class Person(models.Model): name = models.CharField(max_length=30) born = models.ForeignKey(City, models.CASCADE, related_name='+') died = models.ForeignKey(City, models.CASCADE, related_name='+') + + +class PersonProfile(models.Model): + person = models.OneToOneField(Person, models.CASCADE, related_name='profile') diff --git a/tests/select_for_update/tests.py b/tests/select_for_update/tests.py index 707fa0e9ba..6de268cb2b 100644 --- a/tests/select_for_update/tests.py +++ b/tests/select_for_update/tests.py @@ -15,7 +15,7 @@ from django.test import ( ) from django.test.utils import CaptureQueriesContext -from .models import City, Country, Person +from .models import City, Country, Person, PersonProfile class SelectForUpdateTests(TransactionTestCase): @@ -30,6 +30,7 @@ class SelectForUpdateTests(TransactionTestCase): self.city1 = City.objects.create(name='Liberchies', country=self.country1) self.city2 = City.objects.create(name='Samois-sur-Seine', country=self.country2) self.person = Person.objects.create(name='Reinhardt', born=self.city1, died=self.city2) + self.person_profile = PersonProfile.objects.create(person=self.person) # We need another database connection in transaction to test that one # connection issuing a SELECT ... FOR UPDATE will block. @@ -225,13 +226,27 @@ class SelectForUpdateTests(TransactionTestCase): msg = ( 'Invalid field name(s) given in select_for_update(of=(...)): %s. ' 'Only relational fields followed in the query are allowed. ' - 'Choices are: self, born.' + 'Choices are: self, born, profile.' ) for name in ['born__country', 'died', 'died__country']: with self.subTest(name=name): with self.assertRaisesMessage(FieldError, msg % name): with transaction.atomic(): - Person.objects.select_related('born').select_for_update(of=(name,)).get() + Person.objects.select_related( + 'born', 'profile', + ).exclude(profile=None).select_for_update(of=(name,)).get() + + @skipUnlessDBFeature('has_select_for_update', 'has_select_for_update_of') + def test_reverse_one_to_one_of_arguments(self): + """ + Reverse OneToOneFields may be included in of=(...) as long as NULLs + are excluded because LEFT JOIN isn't allowed in SELECT FOR UPDATE. + """ + with transaction.atomic(): + person = Person.objects.select_related( + 'profile', + ).exclude(profile=None).select_for_update(of=('profile',)).get() + self.assertEqual(person.profile, self.person_profile) @skipUnlessDBFeature('has_select_for_update') def test_for_update_after_from(self): |