diff --git a/docs/ref/models/options.txt b/docs/ref/models/options.txt index 60a3064dff..a0ef5b3d4b 100644 --- a/docs/ref/models/options.txt +++ b/docs/ref/models/options.txt @@ -99,6 +99,10 @@ attribute. For tests involving models with ``managed=False``, it's up to you to ensure the correct tables are created as part of the test setup. +If you're interested in changing the Python-level behaviour of a model class, +you *could* use ``managed=True`` and create a copy of an existing model. +However, there's a better approach for that situation: :ref:`proxy-models`. + ``order_with_respect_to`` ------------------------- diff --git a/docs/topics/db/models.txt b/docs/topics/db/models.txt index be500680ec..cb0501faa6 100644 --- a/docs/topics/db/models.txt +++ b/docs/topics/db/models.txt @@ -1117,6 +1117,48 @@ containing the new managers and inherit that after the primary base class:: You probably won't need to do this very often, but, when you do, it's possible. +Differences between proxy inheritance and unmanaged models +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Proxy model inheritance might look fairly similar to creating an unmanaged +model, using the :attr:`~django.db.models.Options.managed` attribute on a +model's ``Meta`` class. The two alternatives are not quite the same and it's +worth considering which one you should use. + +One difference is that you can (and, in fact, must unless you want an empty +model) specify model fields on models with ``Meta.managed=False``. You could, +with careful setting of :attr:`Meta.db_table +` create an unmanaged model that shadowed +an existing model and add Python methods to it. However, that would be very +repetitive and fragile as you need to keep both copies synchronized if you +make any changes. + +The other difference that is more important for proxy models, is how model +managers are handled. Proxy models are intended to behave exactly like the +model they are proxying for. So they inherit the parent model's managers, +including the default manager. In the normal multi-table model inheritance +case, children do not inherit managers from their parents as the custom +managers aren't always appropriate when extra fields are involved. The +:ref:`manager documentation ` has more +details about this latter case. + +When these two features were implemented, attempts were made to squash them +into a single option. It turned out that interactions with inheritance, in +general, and managers, in particular, made the API very complicated and +potentially difficult to understand and use. It turned out that two options +were needed in any case, so the current separation arose. + +So, the general rules are: + + 1. If you are mirroring an existing model or database table and don't want + all the original database table columns, use ``Meta.managed=False``. + That option is normally useful for modeling database views and tables + not under the control of Django. + 2. If you are wanting to change the Python-only behavior of a model, but + keep all the same fields as in the original, use ``Meta.proxy=True``. + This sets things up so that the proxy model is an exact copy of the + storage structure of the original model when data is saved. + Multiple inheritance --------------------