Fixed #19384 -- Documented the behavior of custom managers on abstract models.

This documents the behavior introduced by cc337a74, which is BACKWARDS
INCOMPATIBLE for any attempt to invoke a method on a manager using the
abstract class as the calling class (e.g., AbstractBase.objects.do_something())

Thanks to mhsparks for the report.
This commit is contained in:
Russell Keith-Magee 2012-12-15 20:13:45 +08:00
parent 1e5b0fc4d0
commit 1b646e656e
2 changed files with 30 additions and 0 deletions

View File

@ -341,6 +341,21 @@ Backwards incompatible changes in 1.5
deprecation timeline for a given feature, its removal may appear as a
backwards incompatible change.
Managers on abstract models
~~~~~~~~~~~~~~~~~~~~~~~~~~~
Abstract models are able to define a custom manager, and that manager
:ref:`will be inherited by any concrete models extending the abstract model
<custom-managers-and-inheritance>`. However, if you try to use the abstract
model to call a method on the manager, an exception will now be raised.
Previously, the call would have been permitted, but would have failed as soon
as any database operation was attempted (usually with a "table does not exist"
error from the database).
If you have functionality on a manager that you have been invoking using
the abstract class, you should migrate that logic to a Python
``staticmethod`` or ``classmethod`` on the abstract class.
Context in year archive class-based views
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

View File

@ -274,6 +274,21 @@ it into the inheritance hierarchy *after* the defaults::
# Default manager is CustomManager, but OtherManager is
# also available via the "extra_manager" attribute.
Note that while you can *define* a custom manager on the abstract model, you
can't *invoke* any methods using the abstract model. That is::
ClassA.objects.do_something()
is legal, but::
AbstractBase.objects.do_something()
will raise an exception. This is because managers are intended to encapsulate
logic for managing collections of objects. Since you can't have a collection of
abstract objects, it doesn't make sense to be managing them. If you have
functionality that applies to the abstract model, you should put that functionality
in a ``staticmethod`` or ``classmethod`` on the abstract model.
Implementation concerns
-----------------------