mirror of
https://github.com/django/django.git
synced 2025-10-28 16:16:12 +00:00
Fixed #21961 -- Added support for database-level delete options for ForeignKey.
Thanks Simon Charette for pair programming. Co-authored-by: Nick Stefan <NickStefan12@gmail.com> Co-authored-by: Akash Kumar Sen <71623442+Akash-Kumar-Sen@users.noreply.github.com> Co-authored-by: Simon Charette <charette.s@gmail.com>
This commit is contained in:
@@ -1699,11 +1699,11 @@ relation works.
|
||||
|
||||
.. attribute:: ForeignKey.on_delete
|
||||
|
||||
When an object referenced by a :class:`ForeignKey` is deleted, Django will
|
||||
emulate the behavior of the SQL constraint specified by the
|
||||
:attr:`on_delete` argument. For example, if you have a nullable
|
||||
:class:`ForeignKey` and you want it to be set null when the referenced
|
||||
object is deleted::
|
||||
When an object referenced by a :class:`ForeignKey` is deleted, the
|
||||
referring objects need updating. The :attr:`on_delete` argument specifies
|
||||
how this is done, and whether Django or your database makes the updates.
|
||||
For example, if you have a nullable :class:`ForeignKey` and you want Django
|
||||
to set it to ``None`` when the referenced object is deleted::
|
||||
|
||||
user = models.ForeignKey(
|
||||
User,
|
||||
@@ -1712,8 +1712,21 @@ relation works.
|
||||
null=True,
|
||||
)
|
||||
|
||||
``on_delete`` doesn't create an SQL constraint in the database. Support for
|
||||
database-level cascade options :ticket:`may be implemented later <21961>`.
|
||||
The possible values for :attr:`~ForeignKey.on_delete` are listed below.
|
||||
Import them from :mod:`django.db.models`. The ``DB_*`` variants use the
|
||||
database to prevent deletions or update referring objects, whilst the other
|
||||
values make Django perform the relevant actions.
|
||||
|
||||
The database variants are more efficient because they avoid fetching
|
||||
related objects, but ``pre_delete`` and ``post_delete`` signals won't be
|
||||
sent when ``DB_CASCADE`` is used.
|
||||
|
||||
The database variants cannot be mixed with Python variants (other than
|
||||
:attr:`DO_NOTHING`) in the same model and in models related to each other.
|
||||
|
||||
.. versionchanged:: 6.1
|
||||
|
||||
Support for ``DB_*`` variants of the ``on_delete`` attribute was added.
|
||||
|
||||
The possible values for :attr:`~ForeignKey.on_delete` are found in
|
||||
:mod:`django.db.models`:
|
||||
@@ -1729,6 +1742,13 @@ The possible values for :attr:`~ForeignKey.on_delete` are found in
|
||||
:data:`~django.db.models.signals.post_delete` signals are sent for all
|
||||
deleted objects.
|
||||
|
||||
* .. attribute:: DB_CASCADE
|
||||
|
||||
.. versionadded:: 6.1
|
||||
|
||||
Cascade deletes. Database-level version of :attr:`CASCADE`: the database
|
||||
deletes referred-to rows and the one containing the ``ForeignKey``.
|
||||
|
||||
* .. attribute:: PROTECT
|
||||
|
||||
Prevent deletion of the referenced object by raising
|
||||
@@ -1782,11 +1802,30 @@ The possible values for :attr:`~ForeignKey.on_delete` are found in
|
||||
Set the :class:`ForeignKey` null; this is only possible if
|
||||
:attr:`~Field.null` is ``True``.
|
||||
|
||||
* .. attribute:: DB_SET_NULL
|
||||
|
||||
.. versionadded:: 6.1
|
||||
|
||||
Set the :class:`ForeignKey` value to ``NULL``. This is only possible if
|
||||
:attr:`~Field.null` is ``True``. Database-level version of
|
||||
:attr:`SET_NULL`.
|
||||
|
||||
* .. attribute:: SET_DEFAULT
|
||||
|
||||
Set the :class:`ForeignKey` to its default value; a default for the
|
||||
:class:`ForeignKey` must be set.
|
||||
|
||||
* .. attribute:: DB_SET_DEFAULT
|
||||
|
||||
.. versionadded:: 6.1
|
||||
|
||||
Set the :class:`ForeignKey` value to its :attr:`Field.db_default` value,
|
||||
which must be set. If a row in the referenced table is deleted, the foreign
|
||||
key values in the referencing table will be updated to their
|
||||
:attr:`Field.db_default` values.
|
||||
|
||||
``DB_SET_DEFAULT`` is not supported on MySQL and MariaDB.
|
||||
|
||||
* .. function:: SET()
|
||||
|
||||
Set the :class:`ForeignKey` to the value passed to
|
||||
|
||||
@@ -695,7 +695,11 @@ Issues an SQL ``DELETE`` for the object. This only deletes the object in the
|
||||
database; the Python instance will still exist and will still have data in
|
||||
its fields, except for the primary key set to ``None``. This method returns the
|
||||
number of objects deleted and a dictionary with the number of deletions per
|
||||
object type.
|
||||
object type. The return value will count instances from related models if
|
||||
Django is emulating cascade behavior via Python :attr:`~ForeignKey.on_delete`
|
||||
variants. Otherwise, for database variants such as
|
||||
:attr:`~django.db.models.DB_CASCADE`, the return value will report only
|
||||
instances of the :class:`.QuerySet`'s model.
|
||||
|
||||
For more details, including how to delete objects in bulk, see
|
||||
:ref:`topics-db-queries-delete`.
|
||||
@@ -707,6 +711,10 @@ Sometimes with :ref:`multi-table inheritance <multi-table-inheritance>` you may
|
||||
want to delete only a child model's data. Specifying ``keep_parents=True`` will
|
||||
keep the parent model's data.
|
||||
|
||||
.. versionchanged:: 6.1
|
||||
|
||||
Support for the ``DB_*`` variants of ``on_delete`` attribute was added.
|
||||
|
||||
Pickling objects
|
||||
================
|
||||
|
||||
|
||||
@@ -3036,7 +3036,11 @@ unique field in the order that is specified without conflicts. For example::
|
||||
|
||||
Performs an SQL delete query on all rows in the :class:`.QuerySet` and
|
||||
returns the number of objects deleted and a dictionary with the number of
|
||||
deletions per object type.
|
||||
deletions per object type. The return value will count instances from related
|
||||
models if Django is emulating cascade behavior via Python
|
||||
:attr:`~django.db.models.ForeignKey.on_delete` variants. Otherwise, for
|
||||
database variants such as :attr:`~django.db.models.DB_CASCADE`, the return
|
||||
value will report only instances of the :class:`.QuerySet`'s model.
|
||||
|
||||
The ``delete()`` is applied instantly. You cannot call ``delete()`` on a
|
||||
:class:`.QuerySet` that has had a slice taken or can otherwise no longer be
|
||||
@@ -3073,13 +3077,20 @@ The ``delete()`` method does a bulk delete and does not call any ``delete()``
|
||||
methods on your models. It does, however, emit the
|
||||
:data:`~django.db.models.signals.pre_delete` and
|
||||
:data:`~django.db.models.signals.post_delete` signals for all deleted objects
|
||||
(including cascaded deletions).
|
||||
(including cascaded deletions). Signals won't be sent when ``DB_CASCADE`` is
|
||||
used. Also, ``delete()`` doesn't return information about objects deleted from
|
||||
database variants (``DB_*``) of the
|
||||
:attr:`~django.db.models.ForeignKey.on_delete` argument, e.g. ``DB_CASCADE``.
|
||||
|
||||
Django needs to fetch objects into memory to send signals and handle cascades.
|
||||
However, if there are no cascades and no signals, then Django may take a
|
||||
fast-path and delete objects without fetching into memory. For large
|
||||
deletes this can result in significantly reduced memory usage. The amount of
|
||||
executed queries can be reduced, too.
|
||||
Django won’t need to fetch objects into memory when deleting them in the
|
||||
following cases:
|
||||
|
||||
#. If related fields use ``DB_*`` options.
|
||||
#. If there are no cascades and no delete signal receivers.
|
||||
|
||||
In these cases, Django may take a fast path and delete objects without fetching
|
||||
them, which can result in significantly reduced memory usage and fewer executed
|
||||
queries.
|
||||
|
||||
ForeignKeys which are set to :attr:`~django.db.models.ForeignKey.on_delete`
|
||||
``DO_NOTHING`` do not prevent taking the fast-path in deletion.
|
||||
@@ -3087,6 +3098,10 @@ ForeignKeys which are set to :attr:`~django.db.models.ForeignKey.on_delete`
|
||||
Note that the queries generated in object deletion is an implementation
|
||||
detail subject to change.
|
||||
|
||||
.. versionchanged:: 6.1
|
||||
|
||||
Support for the ``DB_*`` variants of ``on_delete`` attribute was added.
|
||||
|
||||
``as_manager()``
|
||||
~~~~~~~~~~~~~~~~
|
||||
|
||||
|
||||
Reference in New Issue
Block a user