|
| 1 | +Proxy Models |
| 2 | +============ |
| 3 | + |
| 4 | +:pypi:`django-polymorphic` has supported :ref:`proxy models <django:proxy-models>` since they were |
| 5 | +introduced in Django but the default implementation is unintuitive. If a row is created from the |
| 6 | +proxy model the :class:`~django.contrib.contenttypes.models.ContentType` of the proxy class is |
| 7 | +recorded. This allows patterns that need to alter behavior based on which class was used to create |
| 8 | +the row. |
| 9 | + |
| 10 | +**By default the queryset on proxy models will filter on instance_of(ProxyModel) which will exclude |
| 11 | +any rows that were not created from the proxy.** |
| 12 | + |
| 13 | +.. code-block:: python |
| 14 | +
|
| 15 | + from polymorphic.models import PolymorphicModel |
| 16 | +
|
| 17 | + class MyModel(PolymorphicModel): |
| 18 | + ... |
| 19 | +
|
| 20 | + class MyProxy(MyModel): |
| 21 | + class Meta: |
| 22 | + proxy = True |
| 23 | +
|
| 24 | + |
| 25 | + MyModel.objects.create() |
| 26 | + MyProxy.objects.create() |
| 27 | +
|
| 28 | + assert MyModel.objects.count() == 2 |
| 29 | + assert MyProxy.objects.count() == 1 |
| 30 | +
|
| 31 | +This behavior may be unexpected for typical uses of proxy models which involves creating from the |
| 32 | +concrete class then accessing from a proxy in the context where you need the modified proxy |
| 33 | +interface. There is a |
| 34 | +`discussion <https://github.com/jazzband/django-polymorphic/discussions/689>`_ if this should |
| 35 | +continue to be the default behavior in version 5+. |
| 36 | + |
| 37 | +Polymorphic Proxy Queries |
| 38 | +------------------------- |
| 39 | + |
| 40 | +.. versionadded:: 4.3 |
| 41 | + |
| 42 | +If you wish for your proxy model querysets to behave polymorphically by default |
| 43 | +(include all rows created by the proxy and concrete models in the class's inheritance tree) then |
| 44 | +instead of (or in additon to) :attr:`~django.db.models.Options.proxy` set a |
| 45 | +:attr:`Meta.polymorphic_proxy` attribute to True: |
| 46 | + |
| 47 | +.. code-block:: python |
| 48 | +
|
| 49 | + from polymorphic.models import PolymorphicModel |
| 50 | +
|
| 51 | + class MyModel(PolymorphicModel): |
| 52 | + ... |
| 53 | +
|
| 54 | + class MyProxy(MyModel): |
| 55 | + class Meta: |
| 56 | + polymorphc_proxy = True |
| 57 | +
|
| 58 | +
|
| 59 | + MyModel.objects.create() |
| 60 | + MyProxy.objects.create() |
| 61 | +
|
| 62 | + assert MyModel.objects.count() == 2 |
| 63 | + assert MyProxy.objects.count() == 2 |
| 64 | +
|
| 65 | + for proxy in MyProxy.objects.all(): |
| 66 | + assert isinstance(proxy, MyProxy) # |
0 commit comments