diff options
| author | Flavio Curella <flavio.curella@gmail.com> | 2015-07-22 09:43:21 -0500 |
|---|---|---|
| committer | Tim Graham <timograham@gmail.com> | 2015-07-27 18:28:13 -0400 |
| commit | c2e70f02653519db3a49cd48f5158ccad7434d25 (patch) | |
| tree | c0f421a6b0c26a7716c380b3e360fecc74d553fb /docs | |
| parent | 87d55081ea398c65b2503d22ed3907a9175ec729 (diff) | |
Fixed #21127 -- Started deprecation toward requiring on_delete for ForeignKey/OneToOneField
Diffstat (limited to 'docs')
25 files changed, 256 insertions, 129 deletions
diff --git a/docs/internals/deprecation.txt b/docs/internals/deprecation.txt index ae57f5e8f4..a9e60b379f 100644 --- a/docs/internals/deprecation.txt +++ b/docs/internals/deprecation.txt @@ -30,6 +30,9 @@ details on these changes. * ``Field.remote_field.to`` attribute will be removed. +* The ``on_delete`` argument for ``ForeignKey`` and ``OneToOneField`` will be + required. + * ``django.db.models.fields.add_lazy_relation()`` will be removed. * When time zone support is enabled, database backends that don't support time diff --git a/docs/intro/overview.txt b/docs/intro/overview.txt index e9f574a4f5..8cb5651385 100644 --- a/docs/intro/overview.txt +++ b/docs/intro/overview.txt @@ -40,7 +40,7 @@ database-schema problems. Here's a quick example: pub_date = models.DateField() headline = models.CharField(max_length=200) content = models.TextField() - reporter = models.ForeignKey(Reporter) + reporter = models.ForeignKey(Reporter, on_delete=models.CASCADE) def __str__(self): # __unicode__ on Python 2 return self.headline @@ -154,7 +154,7 @@ as easy as registering your model in the admin site: pub_date = models.DateField() headline = models.CharField(max_length=200) content = models.TextField() - reporter = models.ForeignKey(Reporter) + reporter = models.ForeignKey(Reporter, on_delete=models.CASCADE) .. snippet:: :filename: mysite/news/admin.py diff --git a/docs/intro/tutorial02.txt b/docs/intro/tutorial02.txt index 8fef748a88..e1dd7d0bc7 100644 --- a/docs/intro/tutorial02.txt +++ b/docs/intro/tutorial02.txt @@ -141,7 +141,7 @@ These concepts are represented by simple Python classes. Edit the class Choice(models.Model): - question = models.ForeignKey(Question) + question = models.ForeignKey(Question, on_delete=models.CASCADE) choice_text = models.CharField(max_length=200) votes = models.IntegerField(default=0) diff --git a/docs/ref/contrib/admin/admindocs.txt b/docs/ref/contrib/admin/admindocs.txt index 76060ae28e..09837a3550 100644 --- a/docs/ref/contrib/admin/admindocs.txt +++ b/docs/ref/contrib/admin/admindocs.txt @@ -74,8 +74,12 @@ A model with useful documentation might look like this:: """ slug = models.SlugField(help_text="A short label, generally used in URLs.") - author = models.ForeignKey(User) - blog = models.ForeignKey(Blog) + author = models.ForeignKey( + User, + models.SET_NULL, + blank=True, null=True, + ) + blog = models.ForeignKey(Blog, models.CASCADE) ... def publish(self): diff --git a/docs/ref/contrib/admin/index.txt b/docs/ref/contrib/admin/index.txt index 6ade38064c..5e1d37b453 100644 --- a/docs/ref/contrib/admin/index.txt +++ b/docs/ref/contrib/admin/index.txt @@ -1957,7 +1957,7 @@ information. name = models.CharField(max_length=100) class Book(models.Model): - author = models.ForeignKey(Author) + author = models.ForeignKey(Author, on_delete=models.CASCADE) title = models.CharField(max_length=100) You can edit the books authored by an author on the author page. You add @@ -2174,8 +2174,8 @@ Take this model for instance:: from django.db import models class Friendship(models.Model): - to_person = models.ForeignKey(Person, related_name="friends") - from_person = models.ForeignKey(Person, related_name="from_friends") + to_person = models.ForeignKey(Person, on_delete=models.CASCADE, related_name="friends") + from_person = models.ForeignKey(Person, on_delete=models.CASCADE, related_name="from_friends") If you wanted to display an inline on the ``Person`` admin add/change pages you need to explicitly define the foreign key since it is unable to do so @@ -2281,8 +2281,8 @@ models:: members = models.ManyToManyField(Person, through='Membership') class Membership(models.Model): - person = models.ForeignKey(Person) - group = models.ForeignKey(Group) + person = models.ForeignKey(Person, on_delete=models.CASCADE) + group = models.ForeignKey(Group, on_delete=models.CASCADE) date_joined = models.DateField() invite_reason = models.CharField(max_length=64) @@ -2326,7 +2326,7 @@ you have the following models:: class Image(models.Model): image = models.ImageField(upload_to="images") - content_type = models.ForeignKey(ContentType) + content_type = models.ForeignKey(ContentType, on_delete=models.CASCADE) object_id = models.PositiveIntegerField() content_object = GenericForeignKey("content_type", "object_id") diff --git a/docs/ref/contrib/contenttypes.txt b/docs/ref/contrib/contenttypes.txt index 431c3094f1..8173f876c5 100644 --- a/docs/ref/contrib/contenttypes.txt +++ b/docs/ref/contrib/contenttypes.txt @@ -256,7 +256,7 @@ A simple example is a tagging system, which might look like this:: class TaggedItem(models.Model): tag = models.SlugField() - content_type = models.ForeignKey(ContentType) + content_type = models.ForeignKey(ContentType, on_delete=models.CASCADE) object_id = models.PositiveIntegerField() content_object = GenericForeignKey('content_type', 'object_id') diff --git a/docs/ref/contrib/gis/model-api.txt b/docs/ref/contrib/gis/model-api.txt index 8f386ef284..04669a91b8 100644 --- a/docs/ref/contrib/gis/model-api.txt +++ b/docs/ref/contrib/gis/model-api.txt @@ -269,7 +269,7 @@ model:: street = models.CharField(max_length=100) city = models.CharField(max_length=100) state = models.CharField(max_length=2) - zipcode = models.ForeignKey(Zipcode) + zipcode = models.ForeignKey(Zipcode, on_delete=models.CASCADE) objects = models.GeoManager() The geographic manager is needed to do spatial queries on related ``Zipcode`` objects, diff --git a/docs/ref/contrib/sites.txt b/docs/ref/contrib/sites.txt index c91c112f64..c127fa41f1 100644 --- a/docs/ref/contrib/sites.txt +++ b/docs/ref/contrib/sites.txt @@ -117,7 +117,7 @@ like this:: class Article(models.Model): headline = models.CharField(max_length=200) # ... - site = models.ForeignKey(Site) + site = models.ForeignKey(Site, on_delete=models.CASCADE) This has the same benefits as described in the last section. @@ -334,7 +334,7 @@ your model explicitly. For example:: photo = models.FileField(upload_to='/home/photos') photographer_name = models.CharField(max_length=100) pub_date = models.DateField() - site = models.ForeignKey(Site) + site = models.ForeignKey(Site, on_delete=models.CASCADE) objects = models.Manager() on_site = CurrentSiteManager() @@ -371,7 +371,7 @@ demonstrates this:: photo = models.FileField(upload_to='/home/photos') photographer_name = models.CharField(max_length=100) pub_date = models.DateField() - publish_on = models.ForeignKey(Site) + publish_on = models.ForeignKey(Site, on_delete=models.CASCADE) objects = models.Manager() on_site = CurrentSiteManager('publish_on') diff --git a/docs/ref/models/database-functions.txt b/docs/ref/models/database-functions.txt index 336e4afc05..51a2e4b998 100644 --- a/docs/ref/models/database-functions.txt +++ b/docs/ref/models/database-functions.txt @@ -113,7 +113,7 @@ Usage example:: class Comment(models.Model): body = models.TextField() modified = models.DateTimeField(auto_now=True) - blog = models.ForeignKey(Blog) + blog = models.ForeignKey(Blog, on_delete=models.CASCADE) >>> from django.db.models.functions import Greatest >>> blog = Blog.objects.create(body='Greatest is the best.') diff --git a/docs/ref/models/fields.txt b/docs/ref/models/fields.txt index 0921fda6d8..f68223a82c 100644 --- a/docs/ref/models/fields.txt +++ b/docs/ref/models/fields.txt @@ -1116,15 +1116,22 @@ Django also defines a set of fields that represent relations. ``ForeignKey`` -------------- -.. class:: ForeignKey(othermodel, **options) +.. class:: ForeignKey(othermodel, on_delete, **options) A many-to-one relationship. Requires a positional argument: the class to which the model is related. +.. versionchanged:: 1.9 + + ``on_delete`` can now be used as the second positional argument (previously + it was typically only passed as a keyword argument). It will be a required + argument in Django 2.0. + .. _recursive-relationships: To create a recursive relationship -- an object that has a many-to-one -relationship with itself -- use ``models.ForeignKey('self')``. +relationship with itself -- use ``models.ForeignKey('self', +on_delete=models.CASCADE)``. .. _lazy-relationships: @@ -1134,7 +1141,10 @@ you can use the name of the model, rather than the model object itself:: from django.db import models class Car(models.Model): - manufacturer = models.ForeignKey('Manufacturer') + manufacturer = models.ForeignKey( + 'Manufacturer', + on_delete=models.CASCADE, + ) # ... class Manufacturer(models.Model): @@ -1147,7 +1157,10 @@ model above is defined in another application called ``production``, you'd need to use:: class Car(models.Model): - manufacturer = models.ForeignKey('production.Manufacturer') + manufacturer = models.ForeignKey( + 'production.Manufacturer', + on_delete=models.CASCADE, + ) This sort of reference can be useful when resolving circular import dependencies between two applications. @@ -1173,8 +1186,79 @@ deal with the field names of your model object. Arguments ~~~~~~~~~ -:class:`ForeignKey` accepts an extra set of arguments -- all optional -- that -define the details of how the relation works. +:class:`ForeignKey` accepts other arguments that define the details of how the +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:: + + user = models.ForeignKey( + User, + models.SET_NULL, + blank=True, + null=True, + ) + + .. deprecated:: 1.9 + + :attr:`~ForeignKey.on_delete` will become a required argument in Django + 2.0. In older versions it defaults to ``CASCADE``. + +The possible values for :attr:`~ForeignKey.on_delete` are found in +:mod:`django.db.models`: + +* .. attribute:: CASCADE + + Cascade deletes. Django emulates the behavior of the SQL constraint ON + DELETE CASCADE and also deletes the object containing the ForeignKey. + +* .. attribute:: PROTECT + + Prevent deletion of the referenced object by raising + :exc:`~django.db.models.ProtectedError`, a subclass of + :exc:`django.db.IntegrityError`. + +* .. attribute:: SET_NULL + + Set the :class:`ForeignKey` null; this is only possible if + :attr:`~Field.null` is ``True``. + +* .. attribute:: SET_DEFAULT + + Set the :class:`ForeignKey` to its default value; a default for the + :class:`ForeignKey` must be set. + +* .. function:: 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:: + + from django.conf import settings + from django.contrib.auth import get_user_model + from django.db import models + + def get_sentinel_user(): + return get_user_model().objects.get_or_create(username='deleted')[0] + + class MyModel(models.Model): + user = models.ForeignKey( + settings.AUTH_USER_MODEL, + on_delete=models.SET(get_sentinel_user), + ) + +* .. attribute:: DO_NOTHING + + Take no action. If your database backend enforces referential + integrity, this will cause an :exc:`~django.db.IntegrityError` unless + you manually add an SQL ``ON DELETE`` constraint to the database field. .. attribute:: ForeignKey.limit_choices_to @@ -1186,7 +1270,11 @@ define the details of how the relation works. For example:: - staff_member = models.ForeignKey(User, limit_choices_to={'is_staff': True}) + staff_member = models.ForeignKey( + User, + on_delete=models.CASCADE, + limit_choices_to={'is_staff': True}, + ) causes the corresponding field on the ``ModelForm`` to list only ``Users`` that have ``is_staff=True``. This may be helpful in the Django admin. @@ -1231,7 +1319,11 @@ define the details of how the relation works. ensure that the ``User`` model won't have a backwards relation to this model:: - user = models.ForeignKey(User, related_name='+') + user = models.ForeignKey( + User, + on_delete=models.CASCADE, + related_name='+', + ) .. attribute:: ForeignKey.related_query_name @@ -1241,7 +1333,12 @@ define the details of how the relation works. # Declare the ForeignKey with related_query_name class Tag(models.Model): - article = models.ForeignKey(Article, related_name="tags", related_query_name="tag") + article = models.ForeignKey( + Article, + on_delete=models.CASCADE, + related_name="tags", + related_query_name="tag", + ) name = models.CharField(max_length=255) # That's now the name of the reverse filter @@ -1265,65 +1362,6 @@ define the details of how the relation works. If this is set to ``False``, accessing a related object that doesn't exist will raise its ``DoesNotExist`` exception. -.. 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:`~ForeignKey.on_delete` are found in -:mod:`django.db.models`: - -* .. attribute:: CASCADE - - Cascade deletes; the default. - -* .. attribute:: PROTECT - - Prevent deletion of the referenced object by raising - :exc:`~django.db.models.ProtectedError`, a subclass of - :exc:`django.db.IntegrityError`. - -* .. attribute:: SET_NULL - - Set the :class:`ForeignKey` null; this is only possible if - :attr:`~Field.null` is ``True``. - -* .. attribute:: SET_DEFAULT - - Set the :class:`ForeignKey` to its default value; a default for the - :class:`ForeignKey` must be set. - -* .. function:: 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:: - - from django.conf import settings - from django.contrib.auth import get_user_model - from django.db import models - - def get_sentinel_user(): - return get_user_model().objects.get_or_create(username='deleted')[0] - - class MyModel(models.Model): - user = models.ForeignKey(settings.AUTH_USER_MODEL, - on_delete=models.SET(get_sentinel_user)) - -* .. attribute:: DO_NOTHING - - Take no action. If your database backend enforces referential - integrity, this will cause an :exc:`~django.db.IntegrityError` unless - you manually add an SQL ``ON DELETE`` constraint to the database field. - .. attribute:: ForeignKey.swappable Controls the migration framework's reaction if this :class:`ForeignKey` @@ -1367,7 +1405,7 @@ The possible values for :attr:`~ForeignKey.on_delete` are found in allow_unsaved_instance_assignment = True class Book(models.Model): - author = UnsavedForeignKey(Author) + author = UnsavedForeignKey(Author, on_delete=models.CASCADE) .. _ref-manytomany: @@ -1492,12 +1530,20 @@ that control how the relationship functions. class Group(models.Model): name = models.CharField(max_length=128) - members = models.ManyToManyField(Person, through='Membership', through_fields=('group', 'person')) + members = models.ManyToManyField( + Person, + through='Membership', + through_fields=('group', 'person'), + ) class Membership(models.Model): - group = models.ForeignKey(Group) - person = models.ForeignKey(Person) - inviter = models.ForeignKey(Person, related_name="membership_invites") + group = models.ForeignKey(Group, on_delete=models.CASCADE) + person = models.ForeignKey(Person, on_delete=models.CASCADE) + inviter = models.ForeignKey( + Person, + on_delete=models.CASCADE, + related_name="membership_invites", + ) invite_reason = models.CharField(max_length=64) ``Membership`` has *two* foreign keys to ``Person`` (``person`` and @@ -1577,12 +1623,18 @@ relationship at the database level. ``OneToOneField`` ----------------- -.. class:: OneToOneField(othermodel, parent_link=False, **options) +.. class:: OneToOneField(othermodel, on_delete, parent_link=False, **options) A one-to-one relationship. Conceptually, this is similar to a :class:`ForeignKey` with :attr:`unique=True <Field.unique>`, but the "reverse" side of the relation will directly return a single object. +.. versionchanged:: 1.9 + + ``on_delete`` can now be used as the second positional argument (previously + it was typically only passed as a keyword argument). It will be a required + argument in Django 2.0. + This is most useful as the primary key of a model which "extends" another model in some way; :ref:`multi-table-inheritance` is implemented by adding an implicit one-to-one relation from the child @@ -1603,8 +1655,15 @@ With the following example:: from django.db import models class MySpecialUser(models.Model): - user = models.OneToOneField(settings.AUTH_USER_MODEL) - supervisor = models.OneToOneField(settings.AUTH_USER_MODEL, related_name='supervisor_of') + user = models.OneToOneField( + settings.AUTH_USER_MODEL, + on_delete=models.CASCADE, + ) + supervisor = models.OneToOneField( + settings.AUTH_USER_MODEL, + on_delete=models.CASCADE, + related_name='supervisor_of', + ) your resulting ``User`` model will have the following attributes:: @@ -1931,6 +1990,6 @@ have boolean values (rather than ``None``) if the field is a relation type .. attribute:: Field.related_model Points to the model the field relates to. For example, ``Author`` in - ``ForeignKey(Author)``. If a field has a generic relation (such as a - ``GenericForeignKey`` or a ``GenericRelation``) then ``related_model`` - will be ``None``. + ``ForeignKey(Author, on_delete=models.CASCADE)``. If a field has a generic + relation (such as a ``GenericForeignKey`` or a ``GenericRelation``) then + ``related_model`` will be ``None``. diff --git a/docs/ref/models/options.txt b/docs/ref/models/options.txt index e9d8e7131c..918ba0966a 100644 --- a/docs/ref/models/options.txt +++ b/docs/ref/models/options.txt @@ -186,7 +186,7 @@ Django quotes column and table names behind the scenes. # ... class Answer(models.Model): - question = models.ForeignKey(Question) + question = models.ForeignKey(Question, on_delete=models.CASCADE) # ... class Meta: diff --git a/docs/ref/models/querysets.txt b/docs/ref/models/querysets.txt index 3c0e9d0a61..e87a27a9e0 100644 --- a/docs/ref/models/querysets.txt +++ b/docs/ref/models/querysets.txt @@ -350,7 +350,11 @@ related model ordering can change the expected results. Consider this case:: class Event(Model): - parent = models.ForeignKey('self', related_name='children') + parent = models.ForeignKey( + 'self', + on_delete=models.CASCADE, + related_name='children', + ) date = models.DateField() Event.objects.order_by('children__date') @@ -806,11 +810,16 @@ following models:: class Person(models.Model): # ... - hometown = models.ForeignKey(City) + hometown = models.ForeignKey( + City, + on_delete=models.SET_NULL, + blank=True, + null=True, + ) class Book(models.Model): # ... - author = models.ForeignKey(Person) + author = models.ForeignKey(Person, on_delete=models.CASCADE) ... then a call to ``Book.objects.select_related('author__hometown').get(id=4)`` will cache the related ``Person`` *and* the related ``City``:: diff --git a/docs/ref/models/relations.txt b/docs/ref/models/relations.txt index 095ee560c1..9e27e27151 100644 --- a/docs/ref/models/relations.txt +++ b/docs/ref/models/relations.txt @@ -19,7 +19,7 @@ Related objects reference pass class Article(models.Model): - reporter = models.ForeignKey(Reporter) + reporter = models.ForeignKey(Reporter, on_delete=models.CASCADE) In the above example, the methods below will be available on the manager ``reporter.article_set``. diff --git a/docs/releases/1.9.txt b/docs/releases/1.9.txt index eecf86325c..17d0edfa3f 100644 --- a/docs/releases/1.9.txt +++ b/docs/releases/1.9.txt @@ -928,6 +928,19 @@ versions: Its parsing caused bugs with the current syntax, so support for the old syntax will be removed in Django 2.0 following an accelerated deprecation. +``ForeignKey`` and ``OneToOneField`` ``on_delete`` argument +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +In order to increase awareness about cascading model deletion, the +``on_delete`` argument of ``ForeignKey`` and ``OneToOneField`` will be required +in Django 2.0. + +Update models and existing migrations to explicitly set the argument. Since the +default is ``models.CASCADE``, add ``on_delete=models.CASCADE`` to all +``ForeignKey`` and ``OneToOneField``\s that don't use a different option. You +can also pass it as the second positional argument if you don't care about +compatibility with older versions of Django. + ``Field.rel`` changes ~~~~~~~~~~~~~~~~~~~~~ diff --git a/docs/topics/auth/customizing.txt b/docs/topics/auth/customizing.txt index 7d3f6fee9e..289237be18 100644 --- a/docs/topics/auth/customizing.txt +++ b/docs/topics/auth/customizing.txt @@ -312,7 +312,7 @@ you might create an Employee model:: from django.contrib.auth.models import User class Employee(models.Model): - user = models.OneToOneField(User) + user = models.OneToOneField(User, on_delete=models.CASCADE) department = models.CharField(max_length=100) Assuming an existing Employee Fred Smith who has both a User and Employee @@ -443,7 +443,10 @@ different User model. from django.db import models class Article(models.Model): - author = models.ForeignKey(settings.AUTH_USER_MODEL) + author = models.ForeignKey + settings.AUTH_USER_MODEL, + on_delete=models.CASCADE, + ) When connecting to signals sent by the ``User`` model, you should specify the custom model using the :setting:`AUTH_USER_MODEL` setting. For example:: diff --git a/docs/topics/class-based-views/generic-display.txt b/docs/topics/class-based-views/generic-display.txt index f3d922ab3a..98b8955020 100644 --- a/docs/topics/class-based-views/generic-display.txt +++ b/docs/topics/class-based-views/generic-display.txt @@ -104,7 +104,7 @@ We'll be using these models:: class Book(models.Model): title = models.CharField(max_length=100) authors = models.ManyToManyField('Author') - publisher = models.ForeignKey(Publisher) + publisher = models.ForeignKey(Publisher, on_delete=models.CASCADE) publication_date = models.DateField() Now we need to define a view:: diff --git a/docs/topics/class-based-views/generic-editing.txt b/docs/topics/class-based-views/generic-editing.txt index be087d7758..0ada8db42a 100644 --- a/docs/topics/class-based-views/generic-editing.txt +++ b/docs/topics/class-based-views/generic-editing.txt @@ -204,7 +204,7 @@ the foreign key relation to the model: class Author(models.Model): name = models.CharField(max_length=200) - created_by = models.ForeignKey(User) + created_by = models.ForeignKey(User, on_delete=models.CASCADE) # ... diff --git a/docs/topics/db/examples/many_to_one.txt b/docs/topics/db/examples/many_to_one.txt index e43809fd1c..10020a83cb 100644 --- a/docs/topics/db/examples/many_to_one.txt +++ b/docs/topics/db/examples/many_to_one.txt @@ -17,7 +17,7 @@ To define a many-to-one relationship, use :class:`~django.db.models.ForeignKey`: class Article(models.Model): headline = models.CharField(max_length=100) pub_date = models.DateField() - reporter = models.ForeignKey(Reporter) + reporter = models.ForeignKey(Reporter, on_delete=models.CASCADE) def __str__(self): # __unicode__ on Python 2 return self.headline diff --git a/docs/topics/db/examples/one_to_one.txt b/docs/topics/db/examples/one_to_one.txt index f2a3f54508..311ff75d8d 100644 --- a/docs/topics/db/examples/one_to_one.txt +++ b/docs/topics/db/examples/one_to_one.txt @@ -16,7 +16,11 @@ In this example, a ``Place`` optionally can be a ``Restaurant``:: return "%s the place" % self.name class Restaurant(models.Model): - place = models.OneToOneField(Place, primary_key=True) + place = models.OneToOneField( + Place, + on_delete=models.CASCADE, + primary_key=True, + ) serves_hot_dogs = models.BooleanField(default=False) serves_pizza = models.BooleanField(default=False) @@ -24,7 +28,7 @@ In this example, a ``Place`` optionally can be a ``Restaurant``:: return "%s the restaurant" % self.place.name class Waiter(models.Model): - restaurant = models.ForeignKey(Restaurant) + restaurant = models.ForeignKey(Restaurant, on_delete=models.CASCADE) name = models.CharField(max_length=50) def __str__(self): # __unicode__ on Python 2 diff --git a/docs/topics/db/managers.txt b/docs/topics/db/managers.txt index 64d484e85d..bd46a34c07 100644 --- a/docs/topics/db/managers.txt +++ b/docs/topics/db/managers.txt @@ -87,7 +87,7 @@ returns a list of all ``OpinionPoll`` objects, each with an extra objects = PollManager() class Response(models.Model): - poll = models.ForeignKey(OpinionPoll) + poll = models.ForeignKey(OpinionPoll, on_delete=models.CASCADE) person_name = models.CharField(max_length=50) response = models.TextField() diff --git a/docs/topics/db/models.txt b/docs/topics/db/models.txt index c21f231808..ed13e46374 100644 --- a/docs/topics/db/models.txt +++ b/docs/topics/db/models.txt @@ -99,7 +99,7 @@ Example:: instrument = models.CharField(max_length=100) class Album(models.Model): - artist = models.ForeignKey(Musician) + artist = models.ForeignKey(Musician, on_delete=models.CASCADE) name = models.CharField(max_length=100) release_date = models.DateField() num_stars = models.IntegerField() @@ -281,9 +281,17 @@ In this example, the verbose name is ``"first name"``:: :class:`~django.db.models.OneToOneField` require the first argument to be a model class, so use the :attr:`~Field.verbose_name` keyword argument:: - poll = models.ForeignKey(Poll, verbose_name="the related poll") + poll = models.ForeignKey( + Poll, + on_delete=models.CASCADE, + verbose_name="the related poll", + ) sites = models.ManyToManyField(Site, verbose_name="list of sites") - place = models.OneToOneField(Place, verbose_name="related place") + place = models.OneToOneField( + Place, + on_delete=models.CASCADE, + verbose_name="related place", + ) The convention is not to capitalize the first letter of the :attr:`~Field.verbose_name`. Django will automatically capitalize the first @@ -317,7 +325,7 @@ For example, if a ``Car`` model has a ``Manufacturer`` -- that is, a pass class Car(models.Model): - manufacturer = models.ForeignKey(Manufacturer) + manufacturer = models.ForeignKey(Manufacturer, on_delete=models.CASCADE) # ... You can also create :ref:`recursive relationships <recursive-relationships>` (an @@ -331,7 +339,10 @@ above) be the name of the model, lowercase. You can, of course, call the field whatever you want. For example:: class Car(models.Model): - company_that_makes_it = models.ForeignKey(Manufacturer) + company_that_makes_it = models.ForeignKey( + Manufacturer, + on_delete=models.CASCADE, + ) # ... .. seealso:: @@ -445,8 +456,8 @@ something like this:: return self.name class Membership(models.Model): - person = models.ForeignKey(Person) - group = models.ForeignKey(Group) + person = models.ForeignKey(Person, on_delete=models.CASCADE) + group = models.ForeignKey(Group, on_delete=models.CASCADE) date_joined = models.DateField() invite_reason = models.CharField(max_length=64) @@ -621,7 +632,12 @@ just refer to the other model class wherever needed. For example:: class Restaurant(models.Model): # ... - zip_code = models.ForeignKey(ZipCode) + zip_code = models.ForeignKey( + ZipCode, + on_delete=models.SET_NULL, + blank=True, + null=True, + ) Field name restrictions ----------------------- diff --git a/docs/topics/db/queries.txt b/docs/topics/db/queries.txt index c7ff96c8e3..d7617e8b48 100644 --- a/docs/topics/db/queries.txt +++ b/docs/topics/db/queries.txt @@ -1160,8 +1160,8 @@ Example:: You can override the ``FOO_set`` name by setting the :attr:`~django.db.models.ForeignKey.related_name` parameter in the :class:`~django.db.models.ForeignKey` definition. For example, if the ``Entry`` -model was altered to ``blog = ForeignKey(Blog, related_name='entries')``, the -above example code would look like this:: +model was altered to ``blog = ForeignKey(Blog, on_delete=models.CASCADE, +related_name='entries')``, the above example code would look like this:: >>> b = Blog.objects.get(id=1) >>> b.entries.all() # Returns all Entry objects related to Blog. @@ -1284,7 +1284,7 @@ model. For example:: class EntryDetail(models.Model): - entry = models.OneToOneField(Entry) + entry = models.OneToOneField(Entry, on_delete=models.CASCADE) details = models.TextField() ed = EntryDetail.objects.get(id=2) diff --git a/docs/topics/forms/modelforms.txt b/docs/topics/forms/modelforms.txt index 2e75695f53..e9898c6fff 100644 --- a/docs/topics/forms/modelforms.txt +++ b/docs/topics/forms/modelforms.txt @@ -1119,7 +1119,7 @@ you have these two models:: name = models.CharField(max_length=100) class Book(models.Model): - author = models.ForeignKey(Author) + author = models.ForeignKey(Author, on_delete=models.CASCADE) title = models.CharField(max_length=100) If you want to create a formset that allows you to edit books belonging to @@ -1178,8 +1178,16 @@ need to resolve the ambiguity manually using ``fk_name``. For example, consider the following model:: class Friendship(models.Model): - from_friend = models.ForeignKey(Friend, related_name='from_friends') - to_friend = models.ForeignKey(Friend, related_name='friends') + from_friend = models.ForeignKey( + Friend, + on_delete=models.CASCADE, + related_name='from_friends', + ) + to_friend = models.ForeignKey( + Friend, + on_delete=models.CASCADE, + related_name='friends', + ) length_in_months = models.IntegerField() To resolve this, you can use ``fk_name`` to diff --git a/docs/topics/i18n/translation.txt b/docs/topics/i18n/translation.txt index 79b466ee39..d976ddf2ef 100644 --- a/docs/topics/i18n/translation.txt +++ b/docs/topics/i18n/translation.txt @@ -355,8 +355,12 @@ You can mark names of :class:`~django.db.models.ForeignKey`, their :attr:`~django.db.models.Options.verbose_name` options:: class MyThing(models.Model): - kind = models.ForeignKey(ThingKind, related_name='kinds', - verbose_name=_('kind')) + kind = models.ForeignKey( + ThingKind, + on_delete=models.CASCADE, + related_name='kinds', + verbose_name=_('kind'), + ) Just like you would do in :attr:`~django.db.models.Options.verbose_name` you should provide a lowercase verbose name text for the relation as Django will @@ -391,8 +395,12 @@ with the ``short_description`` attribute:: from django.utils.translation import ugettext_lazy as _ class MyThing(models.Model): - kind = models.ForeignKey(ThingKind, related_name='kinds', - verbose_name=_('kind')) + kind = models.ForeignKey( + ThingKind, + on_delete=models.CASCADE, + related_name='kinds', + verbose_name=_('kind'), + ) def is_mouse(self): return self.kind.type == MOUSE_TYPE diff --git a/docs/topics/serialization.txt b/docs/topics/serialization.txt index b48c625fe8..e34553699d 100644 --- a/docs/topics/serialization.txt +++ b/docs/topics/serialization.txt @@ -344,7 +344,7 @@ Consider the following two models:: class Book(models.Model): name = models.CharField(max_length=100) - author = models.ForeignKey(Person) + author = models.ForeignKey(Person, on_delete=models.CASCADE) Ordinarily, serialized data for ``Book`` would use an integer to refer to the author. For example, in JSON, a Book might be serialized as:: @@ -514,7 +514,7 @@ example above:: class Book(models.Model): name = models.CharField(max_length=100) - author = models.ForeignKey(Person) + author = models.ForeignKey(Person, on_delete=models.CASCADE) def natural_key(self): return (self.name,) + self.author.natural_key() |
