|
| 1 | +Deletion |
| 2 | +======== |
| 3 | + |
| 4 | +.. versionadded:: 4.5.0 |
| 5 | + |
| 6 | +There is nothing special about deleting polymorphic models. The same rules apply as to |
| 7 | +:ref:`the deletion of normal Django models <topics-db-queries-delete>` that have parent/child |
| 8 | +relationships up and down a model inheritance hierarchy. Django must walk the model inheritance and |
| 9 | +relationship graph and collect all of the affected objects so that it can correctly order deletion |
| 10 | +SQL statements to respect database constraints and issue signals. |
| 11 | + |
| 12 | +The polymorphic deletion logic is the same as the normal Django deletion logic because Django |
| 13 | +already walks the model inheritance hierarchy. :class:`~polymorphic.query.PolymorphicQuerySet` and |
| 14 | +:class:`~polymorphic.managers.PolymorphicManager` disrupt this process by confusing Django's graph |
| 15 | +walker by returning concrete subclass instances instead of base class instances when it attempts to |
| 16 | +walk reverse relationships to polymorphic models. To prevent this confusion, |
| 17 | +:pypi:`django-polymorphic` wraps the :attr:`~django.db.models.ForeignKey.on_delete` handlers of |
| 18 | +reverse relations to polymorphic models with :class:`~polymorphic.deletion.PolymorphicGuard` |
| 19 | +which disables polymorphic behavior on the related querysets during collection. |
| 20 | + |
| 21 | +**You may define your polymorphic models as you normally would using the standard Django** |
| 22 | +:attr:`~django.db.models.ForeignKey.on_delete` **actions**. |
| 23 | +:class:`~polymorphic.models.PolymorphicModel` will automatically wrap the actions for you. actions |
| 24 | +wrapped with :class:`~polymorphic.deletion.PolymorphicGuard` serialize in migrations as the |
| 25 | +underlying wrapped action. This ensures migrations generated by versions of |
| 26 | +:pypi:`django-polymorphic` after 4.5.0 should be the same as with prior versions. The guard is also |
| 27 | +unnecessary during migrations because Django generates basic managers instead of using the default |
| 28 | +polymorphic managers. |
| 29 | + |
| 30 | +It is a design goal of :pypi:`django-polymorphic` that deletion should just work without any special |
| 31 | +treatment. However if you encounter attribute errors or database integrity errors during deletion |
| 32 | +you may manually wrap the :attr:`~django.db.models.ForeignKey.on_delete` action of reverse relations |
| 33 | +to polymorphic models with :class:`~polymorphic.deletion.PolymorphicGuard` to disable polymorphic |
| 34 | +behavior during deletion collection. If you encounter an issue like this |
| 35 | +`please report it to us <https://github.com/jazzband/django-polymorphic/issues>`_. For example: |
| 36 | + |
| 37 | +.. code-block:: python |
| 38 | +
|
| 39 | + from polymorphic.models import PolymorphicModel |
| 40 | + from polymorphic.deletion import PolymorphicGuard |
| 41 | + from django.db import models |
| 42 | +
|
| 43 | + class MyModel(models.Model): |
| 44 | + # ... |
| 45 | +
|
| 46 | + class RelatedModel(PolymorphicModel): |
| 47 | + my_model = models.ForeignKey( |
| 48 | + MyModel, |
| 49 | + on_delete=PolymorphicGuard(models.CASCADE), |
| 50 | + ) |
| 51 | +
|
0 commit comments