1
0
mirror of https://github.com/django/django.git synced 2025-10-23 21:59:11 +00:00

Fixed #7539, #13067 -- Added on_delete argument to ForeignKey to control cascade behavior. Also refactored deletion for efficiency and code clarity. Many thanks to Johannes Dollinger and Michael Glassford for extensive work on the patch, and to Alex Gaynor, Russell Keith-Magee, and Jacob Kaplan-Moss for review.

git-svn-id: http://code.djangoproject.com/svn/django/trunk@14507 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
Carl Meyer
2010-11-09 16:46:42 +00:00
parent 3ba3294c6b
commit 616b30227d
28 changed files with 850 additions and 608 deletions

View File

@@ -930,7 +930,7 @@ define the details of how the relation works.
If you'd prefer Django didn't create a backwards relation, set ``related_name``
to ``'+'``. For example, this will ensure that the ``User`` model won't get a
backwards relation to this model::
user = models.ForeignKey(User, related_name='+')
.. attribute:: ForeignKey.to_field
@@ -938,6 +938,51 @@ define the details of how the relation works.
The field on the related object that the relation is to. By default, Django
uses the primary key of the related object.
.. versionadded:: 1.3
.. attribute:: ForeignKey.on_delete
When an object referenced by a :class:`ForeignKey` is deleted, Django by
default emulates the behavior of the SQL constraint ``ON DELETE CASCADE``
and also deletes the object containing the ``ForeignKey``. This behavior
can be overridden by specifying 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::
user = models.ForeignKey(User, blank=True, null=True, on_delete=models.SET_NULL)
The possible values for :attr:`on_delete` are found in
:mod:`django.db.models`:
* :attr:`~django.db.models.CASCADE`: Cascade deletes; the default.
* :attr:`~django.db.models.PROTECT`: Prevent deletion of the referenced
object by raising :exc:`django.db.IntegrityError`.
* :attr:`~django.db.models.SET_NULL`: Set the :class:`ForeignKey` null;
this is only possible if :attr:`null` is ``True``.
* :attr:`~django.db.models.SET_DEFAULT`: Set the :class:`ForeignKey` to its
default value; a default for the :class:`ForeignKey` must be set.
* :func:`~django.db.models.SET()`: Set the :class:`ForeignKey` to the value
passed to :func:`~django.db.models.SET()`, or if a callable is passed in,
the result of calling it. In most cases, passing a callable will be
necessary to avoid executing queries at the time your models.py is
imported::
def get_sentinel_user():
return User.objects.get_or_create(username='deleted')[0]
class MyModel(models.Model):
user = models.ForeignKey(User, on_delete=models.SET(get_sentinel_user))
* :attr:`~django.db.models.DO_NOTHING`: Take no action. If your database
backend enforces referential integrity, this will cause an
:exc:`~django.db.IntegrityError` unless you manually add a SQL ``ON
DELETE`` constraint to the database field (perhaps using
:ref:`initial sql<initial-sql>`).
.. _ref-manytomany:
``ManyToManyField``

View File

@@ -1263,14 +1263,20 @@ For example, to delete all the entries in a particular blog::
# Delete all the entries belonging to this Blog.
>>> Entry.objects.filter(blog=b).delete()
Django emulates the SQL constraint ``ON DELETE CASCADE`` -- in other words, any
objects with foreign keys pointing at the objects to be deleted will be deleted
along with them. For example::
By default, Django's :class:`~django.db.models.ForeignKey` emulates the SQL
constraint ``ON DELETE CASCADE`` -- in other words, any objects with foreign
keys pointing at the objects to be deleted will be deleted along with them.
For example::
blogs = Blog.objects.all()
# This will delete all Blogs and all of their Entry objects.
blogs.delete()
.. versionadded:: 1.3
This cascade behavior is customizable via the
:attr:`~django.db.models.ForeignKey.on_delete` argument to the
:class:`~django.db.models.ForeignKey`.
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