summaryrefslogtreecommitdiff
path: root/tests/one_to_one
diff options
context:
space:
mode:
authorLoic Bistuer <loic.bistuer@gmail.com>2014-09-24 00:41:32 +0700
committerLoic Bistuer <loic.bistuer@gmail.com>2014-09-24 02:03:12 +0700
commite043aae9bb2e3fa244f59b07fc16f57476cb80ff (patch)
tree333f0f9d349f150692c63280c06cd655f371c5cd /tests/one_to_one
parent1fd6e13bf2db025dc93482184439cc1a900db276 (diff)
downloaddjango-e043aae9bb2e3fa244f59b07fc16f57476cb80ff.tar.gz
Fixed #23550 -- Normalized get_queryset() of RelatedObjectDescriptor
and ReverseSingleRelatedObjectDescriptor so they actually return QuerySet instances. Also ensured that SingleRelatedObjectDescriptor.get_queryset() accounts for use_for_related_fields=True. This cleanup lays the groundwork for #23533. Thanks Anssi Kääriäinen for the review.
Diffstat (limited to 'tests/one_to_one')
-rw-r--r--tests/one_to_one/models.py21
-rw-r--r--tests/one_to_one/tests.py58
2 files changed, 78 insertions, 1 deletions
diff --git a/tests/one_to_one/models.py b/tests/one_to_one/models.py
index ccb6851bc3..88b0ef6dcf 100644
--- a/tests/one_to_one/models.py
+++ b/tests/one_to_one/models.py
@@ -96,3 +96,24 @@ class Pointer2(models.Model):
class HiddenPointer(models.Model):
target = models.OneToOneField(Target, related_name='hidden+')
+
+
+# Test related objects visibility.
+class SchoolManager(models.Manager):
+ def get_queryset(self):
+ return super(SchoolManager, self).get_queryset().filter(is_public=True)
+
+
+class School(models.Model):
+ is_public = models.BooleanField(default=False)
+ objects = SchoolManager()
+
+
+class DirectorManager(models.Manager):
+ def get_queryset(self):
+ return super(DirectorManager, self).get_queryset().filter(is_temp=False)
+
+class Director(models.Model):
+ is_temp = models.BooleanField(default=False)
+ school = models.OneToOneField(School)
+ objects = DirectorManager()
diff --git a/tests/one_to_one/tests.py b/tests/one_to_one/tests.py
index da0fb5259f..d9eef0b133 100644
--- a/tests/one_to_one/tests.py
+++ b/tests/one_to_one/tests.py
@@ -4,7 +4,7 @@ from django.db import transaction, IntegrityError, connection
from django.test import TestCase
from .models import (Bar, Favorites, HiddenPointer, ManualPrimaryKey, MultiModel,
- Place, RelatedModel, Restaurant, Target, UndergroundBar, Waiter)
+ Place, RelatedModel, Restaurant, School, Director, Target, UndergroundBar, Waiter)
class OneToOneTests(TestCase):
@@ -382,3 +382,59 @@ class OneToOneTests(TestCase):
self.assertFalse(
hasattr(Target, HiddenPointer._meta.get_field('target').related.get_accessor_name())
)
+
+ def test_related_object(self):
+ public_school = School.objects.create(is_public=True)
+ public_director = Director.objects.create(school=public_school, is_temp=False)
+
+ private_school = School.objects.create(is_public=False)
+ private_director = Director.objects.create(school=private_school, is_temp=True)
+
+ # Only one school is available via all() due to the custom default manager.
+ self.assertQuerysetEqual(
+ School.objects.all(),
+ ["<School: School object>"]
+ )
+
+ # Only one director is available via all() due to the custom default manager.
+ self.assertQuerysetEqual(
+ Director.objects.all(),
+ ["<Director: Director object>"]
+ )
+
+ self.assertEqual(public_director.school, public_school)
+ self.assertEqual(public_school.director, public_director)
+
+ # Make sure the base manager is used so that the related objects
+ # is still accessible even if the default manager doesn't normally
+ # allow it.
+ self.assertEqual(private_director.school, private_school)
+
+ # Make sure the base manager is used so that an student can still access
+ # its related school even if the default manager doesn't normally
+ # allow it.
+ self.assertEqual(private_school.director, private_director)
+
+ # If the manager is marked "use_for_related_fields", it'll get used instead
+ # of the "bare" queryset. Usually you'd define this as a property on the class,
+ # but this approximates that in a way that's easier in tests.
+ School.objects.use_for_related_fields = True
+ try:
+ private_director = Director._base_manager.get(pk=private_director.pk)
+ self.assertRaises(School.DoesNotExist, lambda: private_director.school)
+ finally:
+ School.objects.use_for_related_fields = False
+
+ Director.objects.use_for_related_fields = True
+ try:
+ private_school = School._base_manager.get(pk=private_school.pk)
+ self.assertRaises(Director.DoesNotExist, lambda: private_school.director)
+ finally:
+ Director.objects.use_for_related_fields = False
+
+ def test_hasattr_related_object(self):
+ # The exception raised on attribute access when a related object
+ # doesn't exist should be an instance of a subclass of `AttributeError`
+ # refs #21563
+ self.assertFalse(hasattr(Director(), 'director'))
+ self.assertFalse(hasattr(School(), 'school'))