summaryrefslogtreecommitdiff
path: root/django/db/models
diff options
context:
space:
mode:
Diffstat (limited to 'django/db/models')
-rw-r--r--django/db/models/base.py11
-rw-r--r--django/db/models/fields/related.py68
2 files changed, 67 insertions, 12 deletions
diff --git a/django/db/models/base.py b/django/db/models/base.py
index b679d08654..2a8e5fd2c8 100644
--- a/django/db/models/base.py
+++ b/django/db/models/base.py
@@ -18,7 +18,7 @@ from django.db import (
)
from django.db.models import signals
from django.db.models.constants import LOOKUP_SEP
-from django.db.models.deletion import Collector
+from django.db.models.deletion import CASCADE, Collector
from django.db.models.fields import AutoField
from django.db.models.fields.related import (
ForeignObjectRel, ManyToOneRel, OneToOneField, lazy_related_operation,
@@ -230,8 +230,13 @@ class ModelBase(type):
field = parent_links[base_key]
elif not is_proxy:
attr_name = '%s_ptr' % base._meta.model_name
- field = OneToOneField(base, name=attr_name,
- auto_created=True, parent_link=True)
+ field = OneToOneField(
+ base,
+ on_delete=CASCADE,
+ name=attr_name,
+ auto_created=True,
+ parent_link=True,
+ )
# Only add the ptr field if it's not already present;
# e.g. migrations will already have it specified
if not hasattr(new_class, attr_name):
diff --git a/django/db/models/fields/related.py b/django/db/models/fields/related.py
index b038fdf116..c10b2658b5 100644
--- a/django/db/models/fields/related.py
+++ b/django/db/models/fields/related.py
@@ -30,6 +30,7 @@ from django.utils.deprecation import (
from django.utils.encoding import force_text, smart_text
from django.utils.functional import cached_property, curry
from django.utils.translation import ugettext_lazy as _
+from django.utils.version import get_docs_version
RECURSIVE_RELATIONSHIP_CONSTANT = 'self'
@@ -1584,9 +1585,10 @@ class ForeignObject(RelatedField):
related_accessor_class = ForeignRelatedObjectsDescriptor
rel_class = ForeignObjectRel
- def __init__(self, to, from_fields, to_fields, rel=None, related_name=None,
+ def __init__(self, to, on_delete, from_fields, to_fields, rel=None, related_name=None,
related_query_name=None, limit_choices_to=None, parent_link=False,
- on_delete=CASCADE, swappable=True, **kwargs):
+ swappable=True, **kwargs):
+
if rel is None:
rel = self.rel_class(
self, to,
@@ -1650,14 +1652,14 @@ class ForeignObject(RelatedField):
def deconstruct(self):
name, path, args, kwargs = super(ForeignObject, self).deconstruct()
+ kwargs['on_delete'] = self.remote_field.on_delete
kwargs['from_fields'] = self.from_fields
kwargs['to_fields'] = self.to_fields
+
if self.remote_field.related_name is not None:
kwargs['related_name'] = self.remote_field.related_name
if self.remote_field.related_query_name is not None:
kwargs['related_query_name'] = self.remote_field.related_query_name
- if self.remote_field.on_delete != CASCADE:
- kwargs['on_delete'] = self.remote_field.on_delete
if self.remote_field.parent_link:
kwargs['parent_link'] = self.remote_field.parent_link
# Work out string form of "to"
@@ -1866,8 +1868,8 @@ class ForeignKey(ForeignObject):
}
description = _("Foreign Key (type determined by related field)")
- def __init__(self, to, to_field=None, related_name=None, related_query_name=None,
- limit_choices_to=None, parent_link=False, on_delete=CASCADE,
+ def __init__(self, to, on_delete=None, related_name=None, related_query_name=None,
+ limit_choices_to=None, parent_link=False, to_field=None,
db_constraint=True, **kwargs):
try:
to._meta.model_name
@@ -1885,6 +1887,28 @@ class ForeignKey(ForeignObject):
# be correct until contribute_to_class is called. Refs #12190.
to_field = to_field or (to._meta.pk and to._meta.pk.name)
+ if on_delete is None:
+ warnings.warn(
+ "on_delete will be a required arg for %s in Django 2.0. "
+ "Set it to models.CASCADE if you want to maintain the current default behavior. "
+ "See https://docs.djangoproject.com/en/%s/ref/models/fields/"
+ "#django.db.models.ForeignKey.on_delete" % (
+ self.__class__.__name__,
+ get_docs_version(),
+ ),
+ RemovedInDjango20Warning, 2)
+ on_delete = CASCADE
+
+ elif not callable(on_delete):
+ warnings.warn(
+ "The signature for {0} will change in Django 2.0. "
+ "Pass to_field='{1}' as a kwarg instead of as an arg.".format(
+ self.__class__.__name__,
+ on_delete,
+ ),
+ RemovedInDjango20Warning, 2)
+ on_delete, to_field = to_field, on_delete
+
kwargs['rel'] = self.rel_class(
self, to, to_field,
related_name=related_name,
@@ -1897,7 +1921,7 @@ class ForeignKey(ForeignObject):
kwargs['db_index'] = kwargs.get('db_index', True)
super(ForeignKey, self).__init__(
- to, from_fields=['self'], to_fields=[to_field], **kwargs)
+ to, on_delete, from_fields=['self'], to_fields=[to_field], **kwargs)
self.db_constraint = db_constraint
@@ -2101,9 +2125,33 @@ class OneToOneField(ForeignKey):
description = _("One-to-one relationship")
- def __init__(self, to, to_field=None, **kwargs):
+ def __init__(self, to, on_delete=None, to_field=None, **kwargs):
kwargs['unique'] = True
- super(OneToOneField, self).__init__(to, to_field, **kwargs)
+
+ if on_delete is None:
+ warnings.warn(
+ "on_delete will be a required arg for %s in Django 2.0. "
+ "Set it to models.CASCADE if you want to maintain the current default behavior. "
+ "See https://docs.djangoproject.com/en/%s/ref/models/fields/"
+ "#django.db.models.ForeignKey.on_delete" % (
+ self.__class__.__name__,
+ get_docs_version(),
+ ),
+ RemovedInDjango20Warning, 2)
+ on_delete = CASCADE
+
+ elif not callable(on_delete):
+ warnings.warn(
+ "The signature for {0} will change in Django 2.0. "
+ "Pass to_field='{1}' as a kwarg instead of as an arg.".format(
+ self.__class__.__name__,
+ on_delete,
+ ),
+ RemovedInDjango20Warning, 2)
+ to_field = on_delete
+ on_delete = CASCADE # Avoid warning in superclass
+
+ super(OneToOneField, self).__init__(to, on_delete, to_field=to_field, **kwargs)
def deconstruct(self):
name, path, args, kwargs = super(OneToOneField, self).deconstruct()
@@ -2162,12 +2210,14 @@ def create_many_to_many_intermediary_model(field, klass):
related_name='%s+' % name,
db_tablespace=field.db_tablespace,
db_constraint=field.remote_field.db_constraint,
+ on_delete=CASCADE,
),
to: models.ForeignKey(
to_model,
related_name='%s+' % name,
db_tablespace=field.db_tablespace,
db_constraint=field.remote_field.db_constraint,
+ on_delete=CASCADE,
)
})