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
This commit is contained in:
parent
c768bc6f25
commit
593810a501
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
=============
|
||||
|
||||
|
|
|
@ -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.
|
||||
|
||||
"""}
|
||||
|
|
Loading…
Reference in New Issue