mirror of
https://github.com/django/django.git
synced 2025-10-31 09:41:08 +00:00
Fixed #21169 -- Reworked RelatedManager methods use default filtering
The `remove()` and `clear()` methods of the related managers created by `ForeignKey`, `GenericForeignKey`, and `ManyToManyField` suffered from a number of issues. Some operations ran multiple data modifying queries without wrapping them in a transaction, and some operations didn't respect default filtering when it was present (i.e. when the default manager on the related model implemented a custom `get_queryset()`). Fixing the issues introduced some backward incompatible changes: - The implementation of `remove()` for `ForeignKey` related managers changed from a series of `Model.save()` calls to a single `QuerySet.update()` call. The change means that `pre_save` and `post_save` signals aren't called anymore. - The `remove()` and `clear()` methods for `GenericForeignKey` related managers now perform bulk delete so `Model.delete()` isn't called anymore. - The `remove()` and `clear()` methods for `ManyToManyField` related managers perform nested queries when filtering is involved, which may or may not be an issue depending on the database and the data itself. Refs. #3871, #21174. Thanks Anssi Kääriäinen and Tim Graham for the reviews.
This commit is contained in:
committed by
Anssi Kääriäinen
parent
0b3c8fc851
commit
17c3997f68
@@ -2132,6 +2132,8 @@ extract two field values, where only one is expected::
|
||||
inner_qs = Blog.objects.filter(name__contains='Ch').values('name', 'id')
|
||||
entries = Entry.objects.filter(blog__name__in=inner_qs)
|
||||
|
||||
.. _nested-queries-performance:
|
||||
|
||||
.. admonition:: Performance considerations
|
||||
|
||||
Be cautious about using nested queries and understand your database
|
||||
|
||||
@@ -574,6 +574,32 @@ a :exc:`~exceptions.ValueError` when encountering them, you will have to
|
||||
install pytz_. You may be affected by this problem if you use Django's time
|
||||
zone-related date formats or :mod:`django.contrib.syndication`.
|
||||
|
||||
``remove()`` and ``clear()`` methods of related managers
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
The ``remove()`` and ``clear()`` methods of the related managers created by
|
||||
``ForeignKey``, ``GenericForeignKey``, and ``ManyToManyField`` suffered from a
|
||||
number of issues. Some operations ran multiple data modifying queries without
|
||||
wrapping them in a transaction, and some operations didn't respect default
|
||||
filtering when it was present (i.e. when the default manager on the related
|
||||
model implemented a custom ``get_queryset()``).
|
||||
|
||||
Fixing the issues introduced some backward incompatible changes:
|
||||
|
||||
- The default implementation of ``remove()`` for ``ForeignKey`` related managers
|
||||
changed from a series of ``Model.save()`` calls to a single
|
||||
``QuerySet.update()`` call. The change means that ``pre_save`` and
|
||||
``post_save`` signals aren't sent anymore.
|
||||
|
||||
- The ``remove()`` and ``clear()`` methods for ``GenericForeignKey`` related
|
||||
managers now perform bulk delete. The ``Model.delete()`` method isn't called
|
||||
on each instance anymore.
|
||||
|
||||
- The ``remove()`` and ``clear()`` methods for ``ManyToManyField`` related
|
||||
managers perform nested queries when filtering is involved, which may or
|
||||
may not be an issue depending on your database and your data itself.
|
||||
See :ref:`this note <nested-queries-performance>` for more details.
|
||||
|
||||
.. _pytz: https://pypi.python.org/pypi/pytz/
|
||||
|
||||
Miscellaneous
|
||||
|
||||
Reference in New Issue
Block a user