summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJacob Kaplan-Moss <jacob@jacobian.org>2008-08-05 16:13:28 +0000
committerJacob Kaplan-Moss <jacob@jacobian.org>2008-08-05 16:13:28 +0000
commit593810a5014ecaa28215839fb42f03df44a069d0 (patch)
treeddbb5c214c733e41dff49741cb3832579699b6ec
parentc768bc6f25a470f4b555f0f808e9a3b6b1f37066 (diff)
Fixed #7904: added support for a "use_for_related_fields" property on managers. If True, the manager will be used for related object lookups instead of the "bare" QuerySet introduced bu [8107]. Patch from Justin Bronn.
git-svn-id: http://code.djangoproject.com/svn/django/trunk@8212 bcc190cf-cafb-0310-a4f2-bffc1f526a37
-rw-r--r--django/db/models/fields/related.py9
-rw-r--r--docs/model-api.txt11
-rw-r--r--tests/regressiontests/reverse_single_related/models.py17
3 files changed, 33 insertions, 4 deletions
diff --git a/django/db/models/fields/related.py b/django/db/models/fields/related.py
index e8141986da..ab2b9a6c5e 100644
--- a/django/db/models/fields/related.py
+++ b/django/db/models/fields/related.py
@@ -239,7 +239,14 @@ class ReverseSingleRelatedObjectDescriptor(object):
params = {'%s__pk' % self.field.rel.field_name: val}
else:
params = {'%s__exact' % self.field.rel.field_name: val}
- rel_obj = QuerySet(self.field.rel.to).get(**params)
+
+ # If the related manager indicates that it should be used for
+ # related fields, respect that.
+ rel_mgr = self.field.rel.to._default_manager
+ if getattr(rel_mgr, 'use_for_related_fields', False):
+ rel_obj = rel_mgr.get(**params)
+ else:
+ rel_obj = QuerySet(self.field.rel.to).get(**params)
setattr(instance, cache_name, rel_obj)
return rel_obj
diff --git a/docs/model-api.txt b/docs/model-api.txt
index f624e68844..b6a446b50e 100644
--- a/docs/model-api.txt
+++ b/docs/model-api.txt
@@ -1507,6 +1507,17 @@ good idea to be careful in your choice of default manager, in order to
avoid a situation where overriding of ``get_query_set()`` results in
an inability to retrieve objects you'd like to work with.
+Using managers for related object access
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+By default, Django uses a "bare" (i.e. default) manager when accessing related
+objects (i.e. ``choice.poll``). If this default isn't appropriate for your default manager, you can force Django to use a custom manager for related object attributes by giving it a ``use_for_related_fields`` property::
+
+ class MyManager(models.Manager)::
+ use_for_related_fields = True
+
+ ...
+
Model methods
=============
diff --git a/tests/regressiontests/reverse_single_related/models.py b/tests/regressiontests/reverse_single_related/models.py
index c6bbbebd3d..b2b75392aa 100644
--- a/tests/regressiontests/reverse_single_related/models.py
+++ b/tests/regressiontests/reverse_single_related/models.py
@@ -26,7 +26,7 @@ __test__ = {'API_TESTS':"""
>>> private_source = Source.objects.create(is_public=False)
>>> private_item = Item.objects.create(source=private_source)
-Only one source is available via all() due to the custom default manager.
+# Only one source is available via all() due to the custom default manager.
>>> Source.objects.all()
[<Source: Source object>]
@@ -34,10 +34,21 @@ Only one source is available via all() due to the custom default manager.
>>> public_item.source
<Source: Source object>
-Make sure that an item can still access its related source even if the default
-manager doesn't normally allow it.
+# Make sure that an item can still access its related source even if the default
+# manager doesn't normally allow it.
>>> private_item.source
<Source: Source object>
+# 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.
+
+>>> Source.objects.use_for_related_fields = True
+>>> private_item = Item.objects.get(pk=private_item.pk)
+>>> private_item.source
+Traceback (most recent call last):
+ ...
+DoesNotExist: Source matching query does not exist.
+
"""}