diff options
Diffstat (limited to 'django/db/models')
-rw-r--r-- | django/db/models/base.py | 11 | ||||
-rw-r--r-- | django/db/models/fields/related.py | 68 |
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, ) }) |