1
0
mirror of https://github.com/django/django.git synced 2024-12-22 09:05:43 +00:00

Fixed #21127 -- Started deprecation toward requiring on_delete for ForeignKey/OneToOneField

This commit is contained in:
Flavio Curella 2015-07-22 09:43:21 -05:00 committed by Tim Graham
parent 87d55081ea
commit c2e70f0265
176 changed files with 1525 additions and 1008 deletions

View File

@ -23,8 +23,18 @@ class Migration(migrations.Migration):
('object_repr', models.CharField(max_length=200, verbose_name='object repr')),
('action_flag', models.PositiveSmallIntegerField(verbose_name='action flag')),
('change_message', models.TextField(verbose_name='change message', blank=True)),
('content_type', models.ForeignKey(to_field='id', blank=True, to='contenttypes.ContentType', null=True, verbose_name='content type')),
('user', models.ForeignKey(to=settings.AUTH_USER_MODEL, verbose_name='user')),
('content_type', models.ForeignKey(
to_field='id',
on_delete=models.SET_NULL,
blank=True, null=True,
to='contenttypes.ContentType',
verbose_name='content type',
)),
('user', models.ForeignKey(
to=settings.AUTH_USER_MODEL,
on_delete=models.CASCADE,
verbose_name='user',
)),
],
options={
'ordering': ('-action_time',),

View File

@ -27,8 +27,17 @@ class LogEntryManager(models.Manager):
@python_2_unicode_compatible
class LogEntry(models.Model):
action_time = models.DateTimeField(_('action time'), auto_now=True)
user = models.ForeignKey(settings.AUTH_USER_MODEL, verbose_name=_('user'))
content_type = models.ForeignKey(ContentType, verbose_name=_('content type'), blank=True, null=True)
user = models.ForeignKey(
settings.AUTH_USER_MODEL,
models.CASCADE,
verbose_name=_('user'),
)
content_type = models.ForeignKey(
ContentType,
models.SET_NULL,
verbose_name=_('content type'),
blank=True, null=True,
)
object_id = models.TextField(_('object id'), blank=True, null=True)
object_repr = models.CharField(_('object repr'), max_length=200)
action_flag = models.PositiveSmallIntegerField(_('action flag'))

View File

@ -19,7 +19,12 @@ class Migration(migrations.Migration):
fields=[
('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
('name', models.CharField(max_length=50, verbose_name='name')),
('content_type', models.ForeignKey(to='contenttypes.ContentType', to_field='id', verbose_name='content type')),
('content_type', models.ForeignKey(
to='contenttypes.ContentType',
on_delete=models.CASCADE,
to_field='id',
verbose_name='content type',
)),
('codename', models.CharField(max_length=100, verbose_name='codename')),
],
options={

View File

@ -59,7 +59,11 @@ class Permission(models.Model):
created for each Django model.
"""
name = models.CharField(_('name'), max_length=255)
content_type = models.ForeignKey(ContentType, verbose_name=_('content type'))
content_type = models.ForeignKey(
ContentType,
models.CASCADE,
verbose_name=_('content type'),
)
codename = models.CharField(_('codename'), max_length=100)
objects = PermissionManager()

View File

@ -303,6 +303,7 @@ class GenericRelation(ForeignObject):
)
kwargs['blank'] = True
kwargs['on_delete'] = models.CASCADE
kwargs['editable'] = False
kwargs['serialize'] = False

View File

@ -15,7 +15,12 @@ class Migration(migrations.Migration):
name='Redirect',
fields=[
('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
('site', models.ForeignKey(to='sites.Site', to_field='id', verbose_name='site')),
('site', models.ForeignKey(
to='sites.Site',
to_field='id',
on_delete=models.CASCADE,
verbose_name='site',
)),
('old_path', models.CharField(help_text="This should be an absolute path, excluding the domain name. Example: '/events/search/'.", max_length=200, verbose_name='redirect from', db_index=True)),
('new_path', models.CharField(help_text="This can be either an absolute path (as above) or a full URL starting with 'http://'.", max_length=200, verbose_name='redirect to', blank=True)),
],

View File

@ -6,7 +6,7 @@ from django.utils.translation import ugettext_lazy as _
@python_2_unicode_compatible
class Redirect(models.Model):
site = models.ForeignKey(Site, verbose_name=_('site'))
site = models.ForeignKey(Site, models.CASCADE, verbose_name=_('site'))
old_path = models.CharField(_('redirect from'), max_length=200, db_index=True,
help_text=_("This should be an absolute path, excluding the domain name. Example: '/events/search/'."))
new_path = models.CharField(_('redirect to'), max_length=200, blank=True,

View File

@ -40,6 +40,7 @@ class Command(BaseCommand):
yield "# You'll have to do the following manually to clean this up:"
yield "# * Rearrange models' order"
yield "# * Make sure each model has one field with primary_key=True"
yield "# * Make sure each ForeignKey has `on_delete` set to the desidered behavior."
yield (
"# * Remove `managed = False` lines if you wish to allow "
"Django to create, modify, and delete the table"
@ -128,6 +129,9 @@ class Command(BaseCommand):
'' if '.' in field_type else 'models.',
field_type,
)
if field_type.startswith('ForeignKey('):
field_desc += ', models.DO_NOTHING'
if extra_params:
if not field_desc.endswith('('):
field_desc += ', '

View File

@ -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):

View File

@ -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,
)
})

View File

@ -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

View File

@ -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

View File

@ -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)

View File

@ -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):

View File

@ -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")

View File

@ -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')

View File

@ -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,

View File

@ -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')

View File

@ -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.')

View File

@ -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``.

View File

@ -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:

View File

@ -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``::

View File

@ -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``.

View File

@ -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
~~~~~~~~~~~~~~~~~~~~~

View File

@ -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::

View File

@ -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::

View File

@ -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)
# ...

View File

@ -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

View File

@ -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

View File

@ -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()

View File

@ -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
-----------------------

View File

@ -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)

View File

@ -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

View File

@ -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

View File

@ -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()

View File

@ -12,7 +12,7 @@ class Parent(models.Model):
class Child(models.Model):
parent = models.ForeignKey(Parent, editable=False, null=True)
parent = models.ForeignKey(Parent, models.SET_NULL, editable=False, null=True)
name = models.CharField(max_length=30, blank=True)
age = models.IntegerField(null=True, blank=True)
@ -46,12 +46,12 @@ class Group(models.Model):
class Concert(models.Model):
name = models.CharField(max_length=30)
group = models.ForeignKey(Group)
group = models.ForeignKey(Group, models.CASCADE)
class Membership(models.Model):
music = models.ForeignKey(Musician)
group = models.ForeignKey(Group)
music = models.ForeignKey(Musician, models.CASCADE)
group = models.ForeignKey(Group, models.CASCADE)
role = models.CharField(max_length=15)
@ -69,8 +69,8 @@ class ChordsBand(models.Model):
class Invitation(models.Model):
player = models.ForeignKey(ChordsMusician)
band = models.ForeignKey(ChordsBand)
player = models.ForeignKey(ChordsMusician, models.CASCADE)
band = models.ForeignKey(ChordsBand, models.CASCADE)
instrument = models.CharField(max_length=15)
@ -84,7 +84,7 @@ class Swallow(models.Model):
class SwallowOneToOne(models.Model):
swallow = models.OneToOneField(Swallow)
swallow = models.OneToOneField(Swallow, models.CASCADE)
class UnorderedObject(models.Model):

View File

@ -15,7 +15,7 @@ class Album(models.Model):
@python_2_unicode_compatible
class Song(models.Model):
title = models.CharField(max_length=150)
album = models.ForeignKey(Album)
album = models.ForeignKey(Album, models.CASCADE)
original_release = models.DateField(editable=False)
class Meta:
@ -30,8 +30,8 @@ class Song(models.Model):
class TwoAlbumFKAndAnE(models.Model):
album1 = models.ForeignKey(Album, related_name="album1_set")
album2 = models.ForeignKey(Album, related_name="album2_set")
album1 = models.ForeignKey(Album, models.CASCADE, related_name="album1_set")
album2 = models.ForeignKey(Album, models.CASCADE, related_name="album2_set")
e = models.CharField(max_length=1)
@ -47,8 +47,8 @@ class Book(models.Model):
class AuthorsBooks(models.Model):
author = models.ForeignKey(Author)
book = models.ForeignKey(Book)
author = models.ForeignKey(Author, models.CASCADE)
book = models.ForeignKey(Book, models.CASCADE)
featured = models.BooleanField()
@ -57,12 +57,12 @@ class State(models.Model):
class City(models.Model):
state = models.ForeignKey(State)
state = models.ForeignKey(State, models.CASCADE)
class Influence(models.Model):
name = models.TextField()
content_type = models.ForeignKey(ContentType)
content_type = models.ForeignKey(ContentType, models.CASCADE)
object_id = models.PositiveIntegerField()
content_object = GenericForeignKey('content_type', 'object_id')

View File

@ -38,8 +38,8 @@ class Person(models.Model):
"""
first_name = models.CharField(max_length=200, help_text="The person's first name")
last_name = models.CharField(max_length=200, help_text="The person's last name")
company = models.ForeignKey(Company, help_text="place of work")
family = models.ForeignKey(Family, related_name='+', null=True)
company = models.ForeignKey(Company, models.CASCADE, help_text="place of work")
family = models.ForeignKey(Family, models.SET_NULL, related_name='+', null=True)
groups = models.ManyToManyField(Group, help_text="has membership")
def _get_full_name(self):

View File

@ -13,7 +13,13 @@ from django.utils.encoding import python_2_unicode_compatible
class Book(models.Model):
title = models.CharField(max_length=50)
year = models.PositiveIntegerField(null=True, blank=True)
author = models.ForeignKey(User, verbose_name="Verbose Author", related_name='books_authored', blank=True, null=True)
author = models.ForeignKey(
User,
models.SET_NULL,
verbose_name="Verbose Author",
related_name='books_authored',
blank=True, null=True,
)
contributors = models.ManyToManyField(User, verbose_name="Verbose Contributors", related_name='books_contributed', blank=True)
is_best_seller = models.NullBooleanField(default=0)
date_registered = models.DateField(null=True)
@ -34,7 +40,7 @@ class Department(models.Model):
@python_2_unicode_compatible
class Employee(models.Model):
department = models.ForeignKey(Department, to_field="code")
department = models.ForeignKey(Department, models.CASCADE, to_field="code")
name = models.CharField(max_length=100)
def __str__(self):
@ -44,7 +50,7 @@ class Employee(models.Model):
@python_2_unicode_compatible
class TaggedItem(models.Model):
tag = models.SlugField()
content_type = models.ForeignKey(ContentType, related_name='tagged_items')
content_type = models.ForeignKey(ContentType, models.CASCADE, related_name='tagged_items')
object_id = models.PositiveIntegerField()
content_object = GenericForeignKey('content_type', 'object_id')

View File

@ -31,9 +31,9 @@ class Teacher(models.Model):
@python_2_unicode_compatible
class Child(models.Model):
name = models.CharField(max_length=50)
teacher = models.ForeignKey(Teacher)
teacher = models.ForeignKey(Teacher, models.CASCADE)
content_type = models.ForeignKey(ContentType)
content_type = models.ForeignKey(ContentType, models.CASCADE)
object_id = models.PositiveIntegerField()
parent = GenericForeignKey()
@ -52,7 +52,7 @@ class Author(models.Model):
class NonAutoPKBook(models.Model):
rand_pk = models.IntegerField(primary_key=True, editable=False)
author = models.ForeignKey(Author)
author = models.ForeignKey(Author, models.CASCADE)
title = models.CharField(max_length=50)
def save(self, *args, **kwargs):
@ -65,7 +65,7 @@ class NonAutoPKBook(models.Model):
class EditablePKBook(models.Model):
manual_pk = models.IntegerField(primary_key=True)
author = models.ForeignKey(Author)
author = models.ForeignKey(Author, models.CASCADE)
title = models.CharField(max_length=50)
@ -75,7 +75,7 @@ class Holder(models.Model):
class Inner(models.Model):
dummy = models.IntegerField()
holder = models.ForeignKey(Holder)
holder = models.ForeignKey(Holder, models.CASCADE)
readonly = models.CharField("Inner readonly label", max_length=1)
def get_absolute_url(self):
@ -88,7 +88,7 @@ class Holder2(models.Model):
class Inner2(models.Model):
dummy = models.IntegerField()
holder = models.ForeignKey(Holder2)
holder = models.ForeignKey(Holder2, models.CASCADE)
class Holder3(models.Model):
@ -97,7 +97,7 @@ class Holder3(models.Model):
class Inner3(models.Model):
dummy = models.IntegerField()
holder = models.ForeignKey(Holder3)
holder = models.ForeignKey(Holder3, models.CASCADE)
# Models for ticket #8190
@ -108,12 +108,12 @@ class Holder4(models.Model):
class Inner4Stacked(models.Model):
dummy = models.IntegerField(help_text="Awesome stacked help text is awesome.")
holder = models.ForeignKey(Holder4)
holder = models.ForeignKey(Holder4, models.CASCADE)
class Inner4Tabular(models.Model):
dummy = models.IntegerField(help_text="Awesome tabular help text is awesome.")
holder = models.ForeignKey(Holder4)
holder = models.ForeignKey(Holder4, models.CASCADE)
# Models for #12749
@ -127,13 +127,13 @@ class OutfitItem(models.Model):
class Fashionista(models.Model):
person = models.OneToOneField(Person, primary_key=True)
person = models.OneToOneField(Person, models.CASCADE, primary_key=True)
weaknesses = models.ManyToManyField(OutfitItem, through='ShoppingWeakness', blank=True)
class ShoppingWeakness(models.Model):
fashionista = models.ForeignKey(Fashionista)
item = models.ForeignKey(OutfitItem)
fashionista = models.ForeignKey(Fashionista, models.CASCADE)
item = models.ForeignKey(OutfitItem, models.CASCADE)
# Models for #13510
@ -143,7 +143,7 @@ class TitleCollection(models.Model):
class Title(models.Model):
collection = models.ForeignKey(TitleCollection, blank=True, null=True)
collection = models.ForeignKey(TitleCollection, models.SET_NULL, blank=True, null=True)
title1 = models.CharField(max_length=100)
title2 = models.CharField(max_length=100)
@ -155,7 +155,7 @@ class Poll(models.Model):
class Question(models.Model):
poll = models.ForeignKey(Poll)
poll = models.ForeignKey(Poll, models.CASCADE)
class Novel(models.Model):
@ -164,14 +164,14 @@ class Novel(models.Model):
class Chapter(models.Model):
name = models.CharField(max_length=40)
novel = models.ForeignKey(Novel)
novel = models.ForeignKey(Novel, models.CASCADE)
class FootNote(models.Model):
"""
Model added for ticket 19838
"""
chapter = models.ForeignKey(Chapter, on_delete=models.PROTECT)
chapter = models.ForeignKey(Chapter, models.PROTECT)
note = models.CharField(max_length=40)
# Models for #16838
@ -183,17 +183,17 @@ class CapoFamiglia(models.Model):
class Consigliere(models.Model):
name = models.CharField(max_length=100, help_text='Help text for Consigliere')
capo_famiglia = models.ForeignKey(CapoFamiglia, related_name='+')
capo_famiglia = models.ForeignKey(CapoFamiglia, models.CASCADE, related_name='+')
class SottoCapo(models.Model):
name = models.CharField(max_length=100)
capo_famiglia = models.ForeignKey(CapoFamiglia, related_name='+')
capo_famiglia = models.ForeignKey(CapoFamiglia, models.CASCADE, related_name='+')
class ReadOnlyInline(models.Model):
name = models.CharField(max_length=100, help_text='Help text for ReadOnlyInline')
capo_famiglia = models.ForeignKey(CapoFamiglia)
capo_famiglia = models.ForeignKey(CapoFamiglia, models.CASCADE)
# Models for #18433
@ -206,7 +206,7 @@ class ParentModelWithCustomPk(models.Model):
class ChildModel1(models.Model):
my_own_pk = models.CharField(max_length=100, primary_key=True)
name = models.CharField(max_length=100)
parent = models.ForeignKey(ParentModelWithCustomPk)
parent = models.ForeignKey(ParentModelWithCustomPk, models.CASCADE)
def get_absolute_url(self):
return '/child_model1/'
@ -215,7 +215,7 @@ class ChildModel1(models.Model):
class ChildModel2(models.Model):
my_own_pk = models.CharField(max_length=100, primary_key=True)
name = models.CharField(max_length=100)
parent = models.ForeignKey(ParentModelWithCustomPk)
parent = models.ForeignKey(ParentModelWithCustomPk, models.CASCADE)
def get_absolute_url(self):
return '/child_model2/'
@ -224,7 +224,7 @@ class ChildModel2(models.Model):
# Models for #19425
class BinaryTree(models.Model):
name = models.CharField(max_length=100)
parent = models.ForeignKey('self', null=True, blank=True)
parent = models.ForeignKey('self', models.SET_NULL, null=True, blank=True)
# Models for #19524
@ -238,7 +238,7 @@ class ExtraTerrestrial(LifeForm):
class Sighting(models.Model):
et = models.ForeignKey(ExtraTerrestrial)
et = models.ForeignKey(ExtraTerrestrial, models.CASCADE)
place = models.CharField(max_length=100)
@ -250,7 +250,7 @@ class SomeParentModel(models.Model):
class SomeChildModel(models.Model):
name = models.CharField(max_length=1)
position = models.PositiveIntegerField()
parent = models.ForeignKey(SomeParentModel)
parent = models.ForeignKey(SomeParentModel, models.CASCADE)
# Other models
@ -260,6 +260,6 @@ class ProfileCollection(models.Model):
class Profile(models.Model):
collection = models.ForeignKey(ProfileCollection, blank=True, null=True)
collection = models.ForeignKey(ProfileCollection, models.SET_NULL, blank=True, null=True)
first_name = models.CharField(max_length=100)
last_name = models.CharField(max_length=100)

View File

@ -13,7 +13,7 @@ class Band(models.Model):
class Song(models.Model):
band = models.ForeignKey(Band)
band = models.ForeignKey(Band, models.CASCADE)
name = models.CharField(max_length=100)
duration = models.IntegerField()
other_interpreters = models.ManyToManyField(Band, related_name='covers')

View File

@ -5,4 +5,4 @@ from django.db import models
# Regression for #13368. This is an example of a model
# that imports a class that has an abstract base class.
class UserProfile(models.Model):
user = models.OneToOneField(User, primary_key=True)
user = models.OneToOneField(User, models.CASCADE, primary_key=True)

View File

@ -15,7 +15,7 @@ class Article(models.Model):
"""
A simple Article model for testing
"""
site = models.ForeignKey(Site, related_name="admin_articles")
site = models.ForeignKey(Site, models.CASCADE, related_name="admin_articles")
title = models.CharField(max_length=100)
title2 = models.CharField(max_length=100, verbose_name="another name")
created = models.DateTimeField()
@ -31,7 +31,7 @@ class Article(models.Model):
@python_2_unicode_compatible
class Count(models.Model):
num = models.PositiveSmallIntegerField()
parent = models.ForeignKey('self', null=True)
parent = models.ForeignKey('self', models.CASCADE, null=True)
def __str__(self):
return six.text_type(self.num)
@ -42,11 +42,11 @@ class Event(models.Model):
class Location(models.Model):
event = models.OneToOneField(Event, verbose_name='awesome event')
event = models.OneToOneField(Event, models.CASCADE, verbose_name='awesome event')
class Guest(models.Model):
event = models.OneToOneField(Event)
event = models.OneToOneField(Event, models.CASCADE)
name = models.CharField(max_length=255)
class Meta:
@ -54,7 +54,7 @@ class Guest(models.Model):
class EventGuide(models.Model):
event = models.ForeignKey(Event, on_delete=models.DO_NOTHING)
event = models.ForeignKey(Event, models.DO_NOTHING)
class Vehicle(models.Model):
@ -62,7 +62,12 @@ class Vehicle(models.Model):
class VehicleMixin(Vehicle):
vehicle = models.OneToOneField(Vehicle, parent_link=True, related_name='vehicle_%(app_label)s_%(class)s')
vehicle = models.OneToOneField(
Vehicle,
models.CASCADE,
parent_link=True,
related_name='vehicle_%(app_label)s_%(class)s',
)
class Meta:
abstract = True

View File

@ -39,8 +39,8 @@ class Article(models.Model):
title = models.CharField(max_length=100)
content = models.TextField()
date = models.DateTimeField()
section = models.ForeignKey(Section, null=True, blank=True)
sub_section = models.ForeignKey(Section, null=True, blank=True, on_delete=models.SET_NULL, related_name='+')
section = models.ForeignKey(Section, models.CASCADE, null=True, blank=True)
sub_section = models.ForeignKey(Section, models.SET_NULL, null=True, blank=True, related_name='+')
def __str__(self):
return self.title
@ -70,7 +70,7 @@ class Book(models.Model):
@python_2_unicode_compatible
class Promo(models.Model):
name = models.CharField(max_length=100, verbose_name='¿Name?')
book = models.ForeignKey(Book)
book = models.ForeignKey(Book, models.CASCADE)
def __str__(self):
return self.name
@ -80,7 +80,7 @@ class Promo(models.Model):
class Chapter(models.Model):
title = models.CharField(max_length=100, verbose_name='¿Title?')
content = models.TextField()
book = models.ForeignKey(Book)
book = models.ForeignKey(Book, models.CASCADE)
def __str__(self):
return self.title
@ -92,7 +92,7 @@ class Chapter(models.Model):
@python_2_unicode_compatible
class ChapterXtra1(models.Model):
chap = models.OneToOneField(Chapter, verbose_name='¿Chap?')
chap = models.OneToOneField(Chapter, models.CASCADE, verbose_name='¿Chap?')
xtra = models.CharField(max_length=100, verbose_name='¿Xtra?')
def __str__(self):
@ -101,7 +101,7 @@ class ChapterXtra1(models.Model):
@python_2_unicode_compatible
class ChapterXtra2(models.Model):
chap = models.OneToOneField(Chapter, verbose_name='¿Chap?')
chap = models.OneToOneField(Chapter, models.CASCADE, verbose_name='¿Chap?')
xtra = models.CharField(max_length=100, verbose_name='¿Xtra?')
def __str__(self):
@ -146,7 +146,7 @@ class Color2(Color):
@python_2_unicode_compatible
class Thing(models.Model):
title = models.CharField(max_length=20)
color = models.ForeignKey(Color, limit_choices_to={'warm': True})
color = models.ForeignKey(Color, models.CASCADE, limit_choices_to={'warm': True})
pub_date = models.DateField(blank=True, null=True)
def __str__(self):
@ -166,7 +166,7 @@ class Actor(models.Model):
@python_2_unicode_compatible
class Inquisition(models.Model):
expected = models.BooleanField(default=False)
leader = models.ForeignKey(Actor)
leader = models.ForeignKey(Actor, models.CASCADE)
country = models.CharField(max_length=20)
def __str__(self):
@ -176,12 +176,27 @@ class Inquisition(models.Model):
@python_2_unicode_compatible
class Sketch(models.Model):
title = models.CharField(max_length=100)
inquisition = models.ForeignKey(Inquisition, limit_choices_to={'leader__name': 'Palin',
'leader__age': 27,
'expected': False,
})
defendant0 = models.ForeignKey(Actor, limit_choices_to={'title__isnull': False}, related_name='as_defendant0')
defendant1 = models.ForeignKey(Actor, limit_choices_to={'title__isnull': True}, related_name='as_defendant1')
inquisition = models.ForeignKey(
Inquisition,
models.CASCADE,
limit_choices_to={
'leader__name': 'Palin',
'leader__age': 27,
'expected': False,
},
)
defendant0 = models.ForeignKey(
Actor,
models.CASCADE,
limit_choices_to={'title__isnull': False},
related_name='as_defendant0',
)
defendant1 = models.ForeignKey(
Actor,
models.CASCADE,
limit_choices_to={'title__isnull': True},
related_name='as_defendant1',
)
def __str__(self):
return self.title
@ -207,7 +222,12 @@ class Character(models.Model):
@python_2_unicode_compatible
class StumpJoke(models.Model):
variation = models.CharField(max_length=100)
most_recently_fooled = models.ForeignKey(Character, limit_choices_to=today_callable_dict, related_name="+")
most_recently_fooled = models.ForeignKey(
Character,
models.CASCADE,
limit_choices_to=today_callable_dict,
related_name="+",
)
has_fooled_today = models.ManyToManyField(Character, limit_choices_to=today_callable_q, related_name="+")
def __str__(self):
@ -259,7 +279,7 @@ class Account(models.Model):
types of accounts.
"""
username = models.CharField(blank=False, max_length=80)
persona = models.ForeignKey(Persona, related_name="accounts")
persona = models.ForeignKey(Persona, models.CASCADE, related_name="accounts")
servicename = 'generic service'
def __str__(self):
@ -305,7 +325,7 @@ class Podcast(Media):
class Vodcast(Media):
media = models.OneToOneField(Media, primary_key=True, parent_link=True)
media = models.OneToOneField(Media, models.CASCADE, primary_key=True, parent_link=True)
released = models.BooleanField(default=False)
@ -318,7 +338,7 @@ class Parent(models.Model):
class Child(models.Model):
parent = models.ForeignKey(Parent, editable=False)
parent = models.ForeignKey(Parent, models.CASCADE, editable=False)
name = models.CharField(max_length=30, blank=True)
def clean(self):
@ -343,7 +363,7 @@ class Gallery(models.Model):
class Picture(models.Model):
name = models.CharField(max_length=100)
image = models.FileField(storage=temp_storage, upload_to='test_upload')
gallery = models.ForeignKey(Gallery, related_name="pictures")
gallery = models.ForeignKey(Gallery, models.CASCADE, related_name="pictures")
class Language(models.Model):
@ -362,7 +382,7 @@ class Title(models.Model):
class TitleTranslation(models.Model):
title = models.ForeignKey(Title)
title = models.ForeignKey(Title, models.CASCADE)
text = models.CharField(max_length=100)
@ -371,7 +391,7 @@ class Recommender(Title):
class Recommendation(Title):
recommender = models.ForeignKey(Recommender)
recommender = models.ForeignKey(Recommender, models.CASCADE)
class Collector(models.Model):
@ -379,25 +399,25 @@ class Collector(models.Model):
class Widget(models.Model):
owner = models.ForeignKey(Collector)
owner = models.ForeignKey(Collector, models.CASCADE)
name = models.CharField(max_length=100)
class DooHickey(models.Model):
code = models.CharField(max_length=10, primary_key=True)
owner = models.ForeignKey(Collector)
owner = models.ForeignKey(Collector, models.CASCADE)
name = models.CharField(max_length=100)
class Grommet(models.Model):
code = models.AutoField(primary_key=True)
owner = models.ForeignKey(Collector)
owner = models.ForeignKey(Collector, models.CASCADE)
name = models.CharField(max_length=100)
class Whatsit(models.Model):
index = models.IntegerField(primary_key=True)
owner = models.ForeignKey(Collector)
owner = models.ForeignKey(Collector, models.CASCADE)
name = models.CharField(max_length=100)
@ -406,13 +426,13 @@ class Doodad(models.Model):
class FancyDoodad(Doodad):
owner = models.ForeignKey(Collector)
owner = models.ForeignKey(Collector, models.CASCADE)
expensive = models.BooleanField(default=True)
@python_2_unicode_compatible
class Category(models.Model):
collector = models.ForeignKey(Collector)
collector = models.ForeignKey(Collector, models.CASCADE)
order = models.PositiveIntegerField()
class Meta:
@ -429,7 +449,7 @@ def link_posted_default():
class Link(models.Model):
posted = models.DateField(default=link_posted_default)
url = models.URLField()
post = models.ForeignKey("Post")
post = models.ForeignKey("Post", models.CASCADE)
class PrePopulatedPost(models.Model):
@ -439,7 +459,7 @@ class PrePopulatedPost(models.Model):
class PrePopulatedSubPost(models.Model):
post = models.ForeignKey(PrePopulatedPost)
post = models.ForeignKey(PrePopulatedPost, models.CASCADE)
subtitle = models.CharField(max_length=100)
subslug = models.SlugField()
@ -488,7 +508,7 @@ class SuperVillain(Villain):
class FunkyTag(models.Model):
"Because we all know there's only one real use case for GFKs."
name = models.CharField(max_length=25)
content_type = models.ForeignKey(ContentType)
content_type = models.ForeignKey(ContentType, models.CASCADE)
object_id = models.PositiveIntegerField()
content_object = GenericForeignKey('content_type', 'object_id')
@ -499,8 +519,8 @@ class FunkyTag(models.Model):
@python_2_unicode_compatible
class Plot(models.Model):
name = models.CharField(max_length=100)
team_leader = models.ForeignKey(Villain, related_name='lead_plots')
contact = models.ForeignKey(Villain, related_name='contact_plots')
team_leader = models.ForeignKey(Villain, models.CASCADE, related_name='lead_plots')
contact = models.ForeignKey(Villain, models.CASCADE, related_name='contact_plots')
tags = GenericRelation(FunkyTag)
def __str__(self):
@ -510,7 +530,7 @@ class Plot(models.Model):
@python_2_unicode_compatible
class PlotDetails(models.Model):
details = models.CharField(max_length=100)
plot = models.OneToOneField(Plot)
plot = models.OneToOneField(Plot, models.CASCADE)
def __str__(self):
return self.details
@ -520,7 +540,7 @@ class PlotDetails(models.Model):
class SecretHideout(models.Model):
""" Secret! Not registered with the admin! """
location = models.CharField(max_length=100)
villain = models.ForeignKey(Villain)
villain = models.ForeignKey(Villain, models.CASCADE)
def __str__(self):
return self.location
@ -530,7 +550,7 @@ class SecretHideout(models.Model):
class SuperSecretHideout(models.Model):
""" Secret! Not registered with the admin! """
location = models.CharField(max_length=100)
supervillain = models.ForeignKey(SuperVillain)
supervillain = models.ForeignKey(SuperVillain, models.CASCADE)
def __str__(self):
return self.location
@ -539,7 +559,7 @@ class SuperSecretHideout(models.Model):
@python_2_unicode_compatible
class CyclicOne(models.Model):
name = models.CharField(max_length=25)
two = models.ForeignKey('CyclicTwo')
two = models.ForeignKey('CyclicTwo', models.CASCADE)
def __str__(self):
return self.name
@ -548,7 +568,7 @@ class CyclicOne(models.Model):
@python_2_unicode_compatible
class CyclicTwo(models.Model):
name = models.CharField(max_length=25)
one = models.ForeignKey(CyclicOne)
one = models.ForeignKey(CyclicOne, models.CASCADE)
def __str__(self):
return self.name
@ -564,7 +584,7 @@ class Pizza(models.Model):
class Album(models.Model):
owner = models.ForeignKey(User, null=True, blank=True, on_delete=models.SET_NULL)
owner = models.ForeignKey(User, models.SET_NULL, null=True, blank=True)
title = models.CharField(max_length=30)
@ -574,7 +594,7 @@ class Employee(Person):
class WorkHour(models.Model):
datum = models.DateField()
employee = models.ForeignKey(Employee)
employee = models.ForeignKey(Employee, models.CASCADE)
class Question(models.Model):
@ -583,7 +603,7 @@ class Question(models.Model):
@python_2_unicode_compatible
class Answer(models.Model):
question = models.ForeignKey(Question, on_delete=models.PROTECT)
question = models.ForeignKey(Question, models.PROTECT)
answer = models.CharField(max_length=20)
def __str__(self):
@ -722,7 +742,7 @@ class MainPrepopulated(models.Model):
class RelatedPrepopulated(models.Model):
parent = models.ForeignKey(MainPrepopulated)
parent = models.ForeignKey(MainPrepopulated, models.CASCADE)
name = models.CharField(max_length=75)
pubdate = models.DateField()
status = models.CharField(
@ -790,7 +810,7 @@ class DependentChild(models.Model):
Model that depends on validation of the parent class for one of its
fields to validate during clean
"""
parent = models.ForeignKey(ParentWithDependentChildren)
parent = models.ForeignKey(ParentWithDependentChildren, models.CASCADE)
family_name = models.CharField(max_length=255)
@ -824,7 +844,7 @@ class State(models.Model):
class City(models.Model):
state = models.ForeignKey(State)
state = models.ForeignKey(State, models.CASCADE)
name = models.CharField(max_length=100)
def get_absolute_url(self):
@ -832,7 +852,7 @@ class City(models.Model):
class Restaurant(models.Model):
city = models.ForeignKey(City)
city = models.ForeignKey(City, models.CASCADE)
name = models.CharField(max_length=100)
def get_absolute_url(self):
@ -840,7 +860,7 @@ class Restaurant(models.Model):
class Worker(models.Model):
work_at = models.ForeignKey(Restaurant)
work_at = models.ForeignKey(Restaurant, models.CASCADE)
name = models.CharField(max_length=50)
surname = models.CharField(max_length=50)
@ -852,7 +872,10 @@ class ReferencedByParent(models.Model):
class ParentWithFK(models.Model):
fk = models.ForeignKey(
ReferencedByParent, to_field='name', related_name='hidden+',
ReferencedByParent,
models.CASCADE,
to_field='name',
related_name='hidden+',
)
@ -867,7 +890,10 @@ class ReferencedByInline(models.Model):
class InlineReference(models.Model):
fk = models.ForeignKey(
ReferencedByInline, to_field='name', related_name='hidden+',
ReferencedByInline,
models.CASCADE,
to_field='name',
related_name='hidden+',
)
@ -886,8 +912,8 @@ class Ingredient(models.Model):
class RecipeIngredient(models.Model):
ingredient = models.ForeignKey(Ingredient, to_field='iname')
recipe = models.ForeignKey(Recipe, to_field='rname')
ingredient = models.ForeignKey(Ingredient, models.CASCADE, to_field='iname')
recipe = models.ForeignKey(Recipe, models.CASCADE, to_field='rname')
# Model for #23839

View File

@ -32,7 +32,7 @@ class Band(models.Model):
@python_2_unicode_compatible
class Album(models.Model):
band = models.ForeignKey(Band)
band = models.ForeignKey(Band, models.CASCADE)
name = models.CharField(max_length=100)
cover_art = models.FileField(upload_to='albums')
backside_art = MyFileField(upload_to='albums_back', null=True)
@ -49,7 +49,7 @@ class HiddenInventoryManager(models.Manager):
@python_2_unicode_compatible
class Inventory(models.Model):
barcode = models.PositiveIntegerField(unique=True)
parent = models.ForeignKey('self', to_field='barcode', blank=True, null=True)
parent = models.ForeignKey('self', models.SET_NULL, to_field='barcode', blank=True, null=True)
name = models.CharField(blank=False, max_length=20)
hidden = models.BooleanField(default=False)
@ -62,7 +62,12 @@ class Inventory(models.Model):
class Event(models.Model):
main_band = models.ForeignKey(Band, limit_choices_to=models.Q(pk__gt=0), related_name='events_main_band_at')
main_band = models.ForeignKey(
Band,
models.CASCADE,
limit_choices_to=models.Q(pk__gt=0),
related_name='events_main_band_at',
)
supporting_bands = models.ManyToManyField(Band, blank=True, related_name='events_supporting_band_at')
start_date = models.DateField(blank=True, null=True)
start_time = models.TimeField(blank=True, null=True)
@ -73,7 +78,7 @@ class Event(models.Model):
@python_2_unicode_compatible
class Car(models.Model):
owner = models.ForeignKey(User)
owner = models.ForeignKey(User, models.CASCADE)
make = models.CharField(max_length=30)
model = models.CharField(max_length=30)
@ -85,7 +90,7 @@ class CarTire(models.Model):
"""
A single car tire. This to test that a user can only select their own cars.
"""
car = models.ForeignKey(Car)
car = models.ForeignKey(Car, models.CASCADE)
class Honeycomb(models.Model):
@ -98,7 +103,7 @@ class Bee(models.Model):
(Honeycomb) so the corresponding raw ID widget won't have a magnifying
glass link to select related honeycomb instances.
"""
honeycomb = models.ForeignKey(Honeycomb)
honeycomb = models.ForeignKey(Honeycomb, models.CASCADE)
class Individual(models.Model):
@ -108,8 +113,8 @@ class Individual(models.Model):
related instances (rendering will be called programmatically in this case).
"""
name = models.CharField(max_length=20)
parent = models.ForeignKey('self', null=True, on_delete=models.SET_NULL)
soulmate = models.ForeignKey('self', null=True, on_delete=models.CASCADE, related_name='soulmates')
parent = models.ForeignKey('self', models.SET_NULL, null=True)
soulmate = models.ForeignKey('self', models.CASCADE, null=True, related_name='soulmates')
class Company(models.Model):
@ -149,7 +154,7 @@ class School(models.Model):
@python_2_unicode_compatible
class Profile(models.Model):
user = models.ForeignKey('auth.User', 'username')
user = models.ForeignKey('auth.User', models.CASCADE, to_field='username')
def __str__(self):
return self.user.username

View File

@ -31,8 +31,8 @@ class Book(models.Model):
rating = models.FloatField()
price = models.DecimalField(decimal_places=2, max_digits=6)
authors = models.ManyToManyField(Author)
contact = models.ForeignKey(Author, related_name='book_contact_set')
publisher = models.ForeignKey(Publisher)
contact = models.ForeignKey(Author, models.CASCADE, related_name='book_contact_set')
publisher = models.ForeignKey(Publisher, models.CASCADE)
pubdate = models.DateField()
def __str__(self):

View File

@ -28,7 +28,7 @@ class Publisher(models.Model):
class ItemTag(models.Model):
tag = models.CharField(max_length=100)
content_type = models.ForeignKey(ContentType)
content_type = models.ForeignKey(ContentType, models.CASCADE)
object_id = models.PositiveIntegerField()
content_object = GenericForeignKey('content_type', 'object_id')
@ -41,8 +41,8 @@ class Book(models.Model):
rating = models.FloatField()
price = models.DecimalField(decimal_places=2, max_digits=6)
authors = models.ManyToManyField(Author)
contact = models.ForeignKey(Author, related_name='book_contact_set')
publisher = models.ForeignKey(Publisher)
contact = models.ForeignKey(Author, models.CASCADE, related_name='book_contact_set')
publisher = models.ForeignKey(Publisher, models.CASCADE)
pubdate = models.DateField()
tags = GenericRelation(ItemTag)
@ -72,7 +72,7 @@ class Entries(models.Model):
class Clues(models.Model):
ID = models.AutoField(primary_key=True)
EntryID = models.ForeignKey(Entries, verbose_name='Entry', db_column='Entry ID')
EntryID = models.ForeignKey(Entries, models.CASCADE, verbose_name='Entry', db_column='Entry ID')
Clue = models.CharField(max_length=150)
@ -102,10 +102,10 @@ class Bravo(models.Model):
class Charlie(models.Model):
alfa = models.ForeignKey(Alfa, null=True)
bravo = models.ForeignKey(Bravo, null=True)
alfa = models.ForeignKey(Alfa, models.SET_NULL, null=True)
bravo = models.ForeignKey(Bravo, models.SET_NULL, null=True)
class SelfRefFK(models.Model):
name = models.CharField(max_length=50)
parent = models.ForeignKey('self', null=True, blank=True, related_name='children')
parent = models.ForeignKey('self', models.SET_NULL, null=True, blank=True, related_name='children')

View File

@ -30,8 +30,8 @@ class Book(models.Model):
rating = models.FloatField()
price = models.DecimalField(decimal_places=2, max_digits=6)
authors = models.ManyToManyField(Author)
contact = models.ForeignKey(Author, related_name='book_contact_set')
publisher = models.ForeignKey(Publisher)
contact = models.ForeignKey(Author, models.CASCADE, related_name='book_contact_set')
publisher = models.ForeignKey(Publisher, models.CASCADE)
pubdate = models.DateField()
def __str__(self):
@ -65,7 +65,7 @@ class Employee(models.Model):
first_name = models.CharField(max_length=20)
manager = models.BooleanField(default=False)
last_name = models.CharField(max_length=20)
store = models.ForeignKey(Store)
store = models.ForeignKey(Store, models.CASCADE)
age = models.IntegerField()
salary = models.DecimalField(max_digits=8, decimal_places=2)

View File

@ -12,7 +12,7 @@ class RelatedModel(models.Model):
class Meta:
app_label = 'not_installed'
not_installed = models.ForeignKey(NotInstalledModel)
not_installed = models.ForeignKey(NotInstalledModel, models.CASCADE)
class M2MRelatedModel(models.Model):

View File

@ -18,9 +18,9 @@ class CustomUserWithFKManager(BaseUserManager):
class CustomUserWithFK(AbstractBaseUser):
username = models.ForeignKey(Email, related_name='primary')
email = models.ForeignKey(Email, to_field='email', related_name='secondary')
group = models.ForeignKey(Group)
username = models.ForeignKey(Email, models.CASCADE, related_name='primary')
email = models.ForeignKey(Email, models.CASCADE, to_field='email', related_name='secondary')
group = models.ForeignKey(Group, models.CASCADE)
custom_objects = CustomUserWithFKManager()

View File

@ -44,7 +44,7 @@ class VeryLongModelNameZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ(models.Model):
class Tag(models.Model):
name = models.CharField(max_length=30)
content_type = models.ForeignKey(ContentType, related_name='backend_tags')
content_type = models.ForeignKey(ContentType, models.CASCADE, related_name='backend_tags')
object_id = models.PositiveIntegerField()
content_object = GenericForeignKey('content_type', 'object_id')
@ -76,9 +76,13 @@ class ReporterProxy(Reporter):
class Article(models.Model):
headline = models.CharField(max_length=100)
pub_date = models.DateField()
reporter = models.ForeignKey(Reporter)
reporter_proxy = models.ForeignKey(ReporterProxy, null=True,
related_name='reporter_proxy')
reporter = models.ForeignKey(Reporter, models.CASCADE)
reporter_proxy = models.ForeignKey(
ReporterProxy,
models.SET_NULL,
null=True,
related_name='reporter_proxy',
)
def __str__(self):
return self.headline
@ -105,7 +109,7 @@ class Object(models.Model):
@python_2_unicode_compatible
class ObjectReference(models.Model):
obj = models.ForeignKey(Object, db_constraint=False)
obj = models.ForeignKey(Object, models.CASCADE, db_constraint=False)
def __str__(self):
return str(self.obj_id)

View File

@ -28,8 +28,12 @@ class ArticleSelectOnSave(Article):
@python_2_unicode_compatible
class SelfRef(models.Model):
selfref = models.ForeignKey('self', null=True, blank=True,
related_name='+')
selfref = models.ForeignKey(
'self',
models.SET_NULL,
null=True, blank=True,
related_name='+',
)
def __str__(self):
# This method intentionally doesn't work for all cases - part

View File

@ -282,8 +282,12 @@ class CheckFrameworkReservedNamesTests(IsolateModelsMixin, SimpleTestCase):
pass
class ModelWithDescriptorCalledCheck(models.Model):
check = models.ForeignKey(ModelWithRelatedManagerCalledCheck)
article = models.ForeignKey(ModelWithRelatedManagerCalledCheck, related_name='check')
check = models.ForeignKey(ModelWithRelatedManagerCalledCheck, models.CASCADE)
article = models.ForeignKey(
ModelWithRelatedManagerCalledCheck,
models.CASCADE,
related_name='check',
)
errors = checks.run_checks()
expected = [

View File

@ -20,7 +20,7 @@ class Author(models.Model):
class Article(models.Model):
title = models.CharField(max_length=100)
slug = models.SlugField()
author = models.ForeignKey(Author)
author = models.ForeignKey(Author, models.CASCADE)
date_created = models.DateTimeField()
def __str__(self):

View File

@ -173,7 +173,7 @@ class GenericForeignKeyTests(IsolatedModelsTestCase):
def test_content_type_field_pointing_to_wrong_model(self):
class Model(models.Model):
content_type = models.ForeignKey('self') # should point to ContentType
content_type = models.ForeignKey('self', models.CASCADE) # should point to ContentType
object_id = models.PositiveIntegerField()
content_object = GenericForeignKey(
'content_type', 'object_id')
@ -191,7 +191,7 @@ class GenericForeignKeyTests(IsolatedModelsTestCase):
def test_missing_object_id_field(self):
class TaggedItem(models.Model):
content_type = models.ForeignKey(ContentType)
content_type = models.ForeignKey(ContentType, models.CASCADE)
# missing object_id field
content_object = GenericForeignKey()
@ -208,7 +208,7 @@ class GenericForeignKeyTests(IsolatedModelsTestCase):
def test_field_name_ending_with_underscore(self):
class Model(models.Model):
content_type = models.ForeignKey(ContentType)
content_type = models.ForeignKey(ContentType, models.CASCADE)
object_id = models.PositiveIntegerField()
content_object_ = GenericForeignKey(
'content_type', 'object_id')
@ -242,7 +242,7 @@ class GenericForeignKeyTests(IsolatedModelsTestCase):
should raise an exception.
"""
class Model(models.Model):
content_type = models.ForeignKey(ContentType, null=True)
content_type = models.ForeignKey(ContentType, models.SET_NULL, null=True)
object_id = models.PositiveIntegerField(null=True)
content_object = GenericForeignKey('content_type', 'object_id')
@ -271,7 +271,7 @@ class GenericForeignKeyTests(IsolatedModelsTestCase):
name = models.CharField(max_length=50)
class BandMember(models.Model):
band_ct = models.ForeignKey(ContentType)
band_ct = models.ForeignKey(ContentType, models.CASCADE)
band_id = models.PositiveIntegerField()
band = UnsavedGenericForeignKey('band_ct', 'band_id')
first_name = models.CharField(max_length=50)
@ -289,7 +289,7 @@ class GenericRelationshipTests(IsolatedModelsTestCase):
def test_valid_generic_relationship(self):
class TaggedItem(models.Model):
content_type = models.ForeignKey(ContentType)
content_type = models.ForeignKey(ContentType, models.CASCADE)
object_id = models.PositiveIntegerField()
content_object = GenericForeignKey()
@ -301,7 +301,7 @@ class GenericRelationshipTests(IsolatedModelsTestCase):
def test_valid_generic_relationship_with_explicit_fields(self):
class TaggedItem(models.Model):
custom_content_type = models.ForeignKey(ContentType)
custom_content_type = models.ForeignKey(ContentType, models.CASCADE)
custom_object_id = models.PositiveIntegerField()
content_object = GenericForeignKey(
'custom_content_type', 'custom_object_id')
@ -333,7 +333,7 @@ class GenericRelationshipTests(IsolatedModelsTestCase):
def test_valid_self_referential_generic_relationship(self):
class Model(models.Model):
rel = GenericRelation('Model')
content_type = models.ForeignKey(ContentType)
content_type = models.ForeignKey(ContentType, models.CASCADE)
object_id = models.PositiveIntegerField()
content_object = GenericForeignKey(
'content_type', 'object_id')
@ -343,7 +343,7 @@ class GenericRelationshipTests(IsolatedModelsTestCase):
def test_missing_generic_foreign_key(self):
class TaggedItem(models.Model):
content_type = models.ForeignKey(ContentType)
content_type = models.ForeignKey(ContentType, models.CASCADE)
object_id = models.PositiveIntegerField()
class Bookmark(models.Model):
@ -368,7 +368,7 @@ class GenericRelationshipTests(IsolatedModelsTestCase):
pass
class SwappedModel(models.Model):
content_type = models.ForeignKey(ContentType)
content_type = models.ForeignKey(ContentType, models.CASCADE)
object_id = models.PositiveIntegerField()
content_object = GenericForeignKey()
@ -393,7 +393,7 @@ class GenericRelationshipTests(IsolatedModelsTestCase):
def test_field_name_ending_with_underscore(self):
class TaggedItem(models.Model):
content_type = models.ForeignKey(ContentType)
content_type = models.ForeignKey(ContentType, models.CASCADE)
object_id = models.PositiveIntegerField()
content_object = GenericForeignKey()

View File

@ -40,7 +40,13 @@ class Article(models.Model):
Article_ID = models.AutoField(primary_key=True, db_column='Article ID')
headline = models.CharField(max_length=100)
authors = models.ManyToManyField(Author, db_table='my_m2m_table')
primary_author = models.ForeignKey(Author, db_column='Author ID', related_name='primary_set', null=True)
primary_author = models.ForeignKey(
Author,
models.SET_NULL,
db_column='Author ID',
related_name='primary_set',
null=True,
)
def __str__(self):
return self.headline

View File

@ -94,8 +94,8 @@ class Person(models.Model):
last_name = models.CharField(max_length=30)
fun = models.BooleanField(default=False)
favorite_book = models.ForeignKey('Book', null=True, related_name='favorite_books')
favorite_thing_type = models.ForeignKey('contenttypes.ContentType', null=True)
favorite_book = models.ForeignKey('Book', models.SET_NULL, null=True, related_name='favorite_books')
favorite_thing_type = models.ForeignKey('contenttypes.ContentType', models.SET_NULL, null=True)
favorite_thing_id = models.IntegerField(null=True)
favorite_thing = GenericForeignKey('favorite_thing_type', 'favorite_thing_id')
@ -117,8 +117,13 @@ class FunPerson(models.Model):
last_name = models.CharField(max_length=30)
fun = models.BooleanField(default=True)
favorite_book = models.ForeignKey('Book', null=True, related_name='fun_people_favorite_books')
favorite_thing_type = models.ForeignKey('contenttypes.ContentType', null=True)
favorite_book = models.ForeignKey(
'Book',
models.SET_NULL,
null=True,
related_name='fun_people_favorite_books',
)
favorite_thing_type = models.ForeignKey('contenttypes.ContentType', models.SET_NULL, null=True)
favorite_thing_id = models.IntegerField(null=True)
favorite_thing = GenericForeignKey('favorite_thing_type', 'favorite_thing_id')
@ -181,7 +186,7 @@ class RelatedModel(models.Model):
class RestrictedModel(models.Model):
name = models.CharField(max_length=50)
is_public = models.BooleanField(default=False)
related = models.ForeignKey(RelatedModel)
related = models.ForeignKey(RelatedModel, models.CASCADE)
objects = RestrictedManager()
plain_manager = models.Manager()
@ -194,7 +199,7 @@ class RestrictedModel(models.Model):
class OneToOneRestrictedModel(models.Model):
name = models.CharField(max_length=50)
is_public = models.BooleanField(default=False)
related = models.OneToOneField(RelatedModel)
related = models.OneToOneField(RelatedModel, models.CASCADE)
objects = RestrictedManager()
plain_manager = models.Manager()

View File

@ -48,4 +48,4 @@ class Bar(models.Model):
class Foo(models.Model):
bar = models.ForeignKey(Bar)
bar = models.ForeignKey(Bar, models.CASCADE)

View File

@ -17,7 +17,7 @@ class Article(models.Model):
@python_2_unicode_compatible
class Comment(models.Model):
article = models.ForeignKey(Article, related_name="comments")
article = models.ForeignKey(Article, models.CASCADE, related_name="comments")
text = models.TextField()
pub_date = models.DateField()
approval_date = models.DateField(null=True)

View File

@ -17,7 +17,7 @@ class Article(models.Model):
@python_2_unicode_compatible
class Comment(models.Model):
article = models.ForeignKey(Article, related_name="comments")
article = models.ForeignKey(Article, models.CASCADE, related_name="comments")
text = models.TextField()
pub_date = models.DateTimeField()
approval_date = models.DateTimeField(null=True)

View File

@ -37,7 +37,7 @@ class Article(models.Model):
class Fan(models.Model):
name = models.CharField(max_length=50)
age = models.PositiveSmallIntegerField(default=30)
author = models.ForeignKey(Author, related_name='fans')
author = models.ForeignKey(Author, models.CASCADE, related_name='fans')
def __str__(self):
return self.name

View File

@ -15,7 +15,7 @@ class Secondary(models.Model):
class Primary(models.Model):
name = models.CharField(max_length=50)
value = models.CharField(max_length=50)
related = models.ForeignKey(Secondary)
related = models.ForeignKey(Secondary, models.CASCADE)
def __str__(self):
return self.name

View File

@ -18,7 +18,7 @@ class Item(models.Model):
class RelatedItem(models.Model):
item = models.ForeignKey(Item)
item = models.ForeignKey(Item, models.CASCADE)
class ProxyRelated(RelatedItem):
@ -34,8 +34,8 @@ class Child(models.Model):
@python_2_unicode_compatible
class Leaf(models.Model):
name = models.CharField(max_length=10)
child = models.ForeignKey(Child)
second_child = models.ForeignKey(Child, related_name="other", null=True)
child = models.ForeignKey(Child, models.CASCADE)
second_child = models.ForeignKey(Child, models.SET_NULL, related_name="other", null=True)
value = models.IntegerField(default=42)
def __str__(self):
@ -62,21 +62,21 @@ class SimpleItem(models.Model):
class Feature(models.Model):
item = models.ForeignKey(SimpleItem)
item = models.ForeignKey(SimpleItem, models.CASCADE)
class SpecialFeature(models.Model):
feature = models.ForeignKey(Feature)
feature = models.ForeignKey(Feature, models.CASCADE)
class OneToOneItem(models.Model):
item = models.OneToOneField(Item, related_name="one_to_one_item")
item = models.OneToOneField(Item, models.CASCADE, related_name="one_to_one_item")
name = models.CharField(max_length=15)
class ItemAndSimpleItem(models.Model):
item = models.ForeignKey(Item)
simple = models.ForeignKey(SimpleItem)
item = models.ForeignKey(Item, models.CASCADE)
simple = models.ForeignKey(SimpleItem, models.CASCADE)
class Profile(models.Model):
@ -88,8 +88,8 @@ class Location(models.Model):
class Request(models.Model):
profile = models.ForeignKey(Profile, null=True, blank=True)
location = models.ForeignKey(Location)
profile = models.ForeignKey(Profile, models.SET_NULL, null=True, blank=True)
location = models.ForeignKey(Location, models.CASCADE)
items = models.ManyToManyField(Item)
request1 = models.CharField(default='request1', max_length=1000)

View File

@ -17,15 +17,15 @@ def get_default_r():
class S(models.Model):
r = models.ForeignKey(R)
r = models.ForeignKey(R, models.CASCADE)
class T(models.Model):
s = models.ForeignKey(S)
s = models.ForeignKey(S, models.CASCADE)
class U(models.Model):
t = models.ForeignKey(T)
t = models.ForeignKey(T, models.CASCADE)
class RChild(R):
@ -35,33 +35,33 @@ class RChild(R):
class A(models.Model):
name = models.CharField(max_length=30)
auto = models.ForeignKey(R, related_name="auto_set")
auto_nullable = models.ForeignKey(R, null=True,
auto = models.ForeignKey(R, models.CASCADE, related_name="auto_set")
auto_nullable = models.ForeignKey(R, models.CASCADE, null=True,
related_name='auto_nullable_set')
setvalue = models.ForeignKey(R, on_delete=models.SET(get_default_r),
setvalue = models.ForeignKey(R, models.SET(get_default_r),
related_name='setvalue')
setnull = models.ForeignKey(R, on_delete=models.SET_NULL, null=True,
setnull = models.ForeignKey(R, models.SET_NULL, null=True,
related_name='setnull_set')
setdefault = models.ForeignKey(R, on_delete=models.SET_DEFAULT,
setdefault = models.ForeignKey(R, models.SET_DEFAULT,
default=get_default_r, related_name='setdefault_set')
setdefault_none = models.ForeignKey(R, on_delete=models.SET_DEFAULT,
setdefault_none = models.ForeignKey(R, models.SET_DEFAULT,
default=None, null=True, related_name='setnull_nullable_set')
cascade = models.ForeignKey(R, on_delete=models.CASCADE,
cascade = models.ForeignKey(R, models.CASCADE,
related_name='cascade_set')
cascade_nullable = models.ForeignKey(R, on_delete=models.CASCADE, null=True,
cascade_nullable = models.ForeignKey(R, models.CASCADE, null=True,
related_name='cascade_nullable_set')
protect = models.ForeignKey(R, on_delete=models.PROTECT, null=True)
donothing = models.ForeignKey(R, on_delete=models.DO_NOTHING, null=True,
protect = models.ForeignKey(R, models.PROTECT, null=True)
donothing = models.ForeignKey(R, models.DO_NOTHING, null=True,
related_name='donothing_set')
child = models.ForeignKey(RChild, related_name="child")
child_setnull = models.ForeignKey(RChild, on_delete=models.SET_NULL, null=True,
child = models.ForeignKey(RChild, models.CASCADE, related_name="child")
child_setnull = models.ForeignKey(RChild, models.SET_NULL, null=True,
related_name="child_setnull")
# A OneToOneField is just a ForeignKey unique=True, so we don't duplicate
# all the tests; just one smoke test to ensure on_delete works for it as
# well.
o2o_setnull = models.ForeignKey(R, null=True,
on_delete=models.SET_NULL, related_name="o2o_nullable_set")
o2o_setnull = models.ForeignKey(R, models.SET_NULL, null=True,
related_name="o2o_nullable_set")
def create_a(name):
@ -86,13 +86,13 @@ class M(models.Model):
class MR(models.Model):
m = models.ForeignKey(M)
r = models.ForeignKey(R)
m = models.ForeignKey(M, models.CASCADE)
r = models.ForeignKey(R, models.CASCADE)
class MRNull(models.Model):
m = models.ForeignKey(M)
r = models.ForeignKey(R, null=True, on_delete=models.SET_NULL)
m = models.ForeignKey(M, models.CASCADE)
r = models.ForeignKey(R, models.SET_NULL, null=True)
class Avatar(models.Model):
@ -100,15 +100,15 @@ class Avatar(models.Model):
class User(models.Model):
avatar = models.ForeignKey(Avatar, null=True)
avatar = models.ForeignKey(Avatar, models.CASCADE, null=True)
class HiddenUser(models.Model):
r = models.ForeignKey(R, related_name="+")
r = models.ForeignKey(R, models.CASCADE, related_name="+")
class HiddenUserProfile(models.Model):
user = models.ForeignKey(HiddenUser)
user = models.ForeignKey(HiddenUser, models.CASCADE)
class M2MTo(models.Model):
@ -132,4 +132,4 @@ class Base(models.Model):
class RelToBase(models.Model):
base = models.ForeignKey(Base, on_delete=models.DO_NOTHING)
base = models.ForeignKey(Base, models.DO_NOTHING)

View File

@ -8,12 +8,12 @@ from django.db import models
class Award(models.Model):
name = models.CharField(max_length=25)
object_id = models.PositiveIntegerField()
content_type = models.ForeignKey(ContentType)
content_type = models.ForeignKey(ContentType, models.CASCADE)
content_object = GenericForeignKey()
class AwardNote(models.Model):
award = models.ForeignKey(Award)
award = models.ForeignKey(Award, models.CASCADE)
note = models.CharField(max_length=100)
@ -36,13 +36,13 @@ class Child(models.Model):
class PlayedWith(models.Model):
child = models.ForeignKey(Child)
toy = models.ForeignKey(Toy)
child = models.ForeignKey(Child, models.CASCADE)
toy = models.ForeignKey(Toy, models.CASCADE)
date = models.DateField(db_column='date_col')
class PlayedWithNote(models.Model):
played = models.ForeignKey(PlayedWith)
played = models.ForeignKey(PlayedWith, models.CASCADE)
note = models.TextField()
@ -63,7 +63,7 @@ class Food(models.Model):
class Eaten(models.Model):
food = models.ForeignKey(Food, to_field="name")
food = models.ForeignKey(Food, models.CASCADE, to_field="name")
meal = models.CharField(max_length=20)
@ -75,16 +75,16 @@ class Policy(models.Model):
class Version(models.Model):
policy = models.ForeignKey(Policy)
policy = models.ForeignKey(Policy, models.CASCADE)
class Location(models.Model):
version = models.ForeignKey(Version, blank=True, null=True)
version = models.ForeignKey(Version, models.SET_NULL, blank=True, null=True)
class Item(models.Model):
version = models.ForeignKey(Version)
location = models.ForeignKey(Location, blank=True, null=True)
version = models.ForeignKey(Version, models.CASCADE)
location = models.ForeignKey(Location, models.SET_NULL, blank=True, null=True)
# Models for #16128
@ -104,15 +104,15 @@ class Photo(Image):
class FooImage(models.Model):
my_image = models.ForeignKey(Image)
my_image = models.ForeignKey(Image, models.CASCADE)
class FooFile(models.Model):
my_file = models.ForeignKey(File)
my_file = models.ForeignKey(File, models.CASCADE)
class FooPhoto(models.Model):
my_photo = models.ForeignKey(Photo)
my_photo = models.ForeignKey(Photo, models.CASCADE)
class FooFileProxy(FooFile):
@ -126,7 +126,7 @@ class OrgUnit(models.Model):
class Login(models.Model):
description = models.CharField(max_length=32)
orgunit = models.ForeignKey(OrgUnit)
orgunit = models.ForeignKey(OrgUnit, models.CASCADE)
class House(models.Model):
@ -135,7 +135,7 @@ class House(models.Model):
class OrderedPerson(models.Model):
name = models.CharField(max_length=32)
lives_in = models.ForeignKey(House)
lives_in = models.ForeignKey(House, models.CASCADE)
class Meta:
ordering = ['name']

View File

@ -7,8 +7,13 @@ from django.utils.encoding import python_2_unicode_compatible
@python_2_unicode_compatible
class Tag(models.Model):
name = models.CharField(max_length=10)
parent = models.ForeignKey('self', blank=True, null=True,
related_name='children')
parent = models.ForeignKey(
'self',
models.SET_NULL,
blank=True,
null=True,
related_name='children',
)
class Meta:
ordering = ['name']
@ -20,14 +25,19 @@ class Tag(models.Model):
@python_2_unicode_compatible
class Celebrity(models.Model):
name = models.CharField("Name", max_length=20)
greatest_fan = models.ForeignKey("Fan", null=True, unique=True)
greatest_fan = models.ForeignKey(
"Fan",
models.SET_NULL,
null=True,
unique=True,
)
def __str__(self):
return self.name
class Fan(models.Model):
fan_of = models.ForeignKey(Celebrity)
fan_of = models.ForeignKey(Celebrity, models.CASCADE)
@python_2_unicode_compatible
@ -44,8 +54,8 @@ class Staff(models.Model):
@python_2_unicode_compatible
class StaffTag(models.Model):
staff = models.ForeignKey(Staff)
tag = models.ForeignKey(Tag)
staff = models.ForeignKey(Staff, models.CASCADE)
tag = models.ForeignKey(Tag, models.CASCADE)
def __str__(self):
return "%s -> %s" % (self.tag, self.staff)

View File

@ -25,9 +25,11 @@ class Company(models.Model):
num_chairs = models.PositiveIntegerField()
ceo = models.ForeignKey(
Employee,
models.CASCADE,
related_name='company_ceo_set')
point_of_contact = models.ForeignKey(
Employee,
models.SET_NULL,
related_name='company_point_of_contact_set',
null=True)

View File

@ -39,7 +39,7 @@ class CaseTestModel(models.Model):
time = models.TimeField(null=True, db_column='time_field')
url = models.URLField(default='')
uuid = models.UUIDField(null=True)
fk = models.ForeignKey('self', null=True)
fk = models.ForeignKey('self', models.CASCADE, null=True)
def __str__(self):
return "%i, %s" % (self.integer, self.string)
@ -47,7 +47,7 @@ class CaseTestModel(models.Model):
@python_2_unicode_compatible
class O2OCaseTestModel(models.Model):
o2o = models.OneToOneField(CaseTestModel, related_name='o2o_rel')
o2o = models.OneToOneField(CaseTestModel, models.CASCADE, related_name='o2o_rel')
integer = models.IntegerField()
def __str__(self):
@ -56,7 +56,7 @@ class O2OCaseTestModel(models.Model):
@python_2_unicode_compatible
class FKCaseTestModel(models.Model):
fk = models.ForeignKey(CaseTestModel, related_name='fk_rel')
fk = models.ForeignKey(CaseTestModel, models.CASCADE, related_name='fk_rel')
integer = models.IntegerField()
def __str__(self):

View File

@ -10,7 +10,7 @@ from django.utils.encoding import python_2_unicode_compatible
@python_2_unicode_compatible
class RevisionableModel(models.Model):
base = models.ForeignKey('self', null=True)
base = models.ForeignKey('self', models.SET_NULL, null=True)
title = models.CharField(blank=True, max_length=255)
when = models.DateTimeField(default=datetime.datetime.now)
@ -32,7 +32,7 @@ class RevisionableModel(models.Model):
class Order(models.Model):
created_by = models.ForeignKey(User)
created_by = models.ForeignKey(User, models.CASCADE)
text = models.TextField()

View File

@ -23,7 +23,7 @@ class FieldDeconstructionTests(SimpleTestCase):
self.assertEqual(name, "is_awesome_test")
self.assertIsInstance(name, six.text_type)
# Now try with a ForeignKey
field = models.ForeignKey("some_fake.ModelName")
field = models.ForeignKey("some_fake.ModelName", models.CASCADE)
name, path, args, kwargs = field.deconstruct()
self.assertIsNone(name)
field.set_attributes_from_name("author")
@ -177,55 +177,55 @@ class FieldDeconstructionTests(SimpleTestCase):
def test_foreign_key(self):
# Test basic pointing
from django.contrib.auth.models import Permission
field = models.ForeignKey("auth.Permission")
field = models.ForeignKey("auth.Permission", models.CASCADE)
field.remote_field.model = Permission
field.remote_field.field_name = "id"
name, path, args, kwargs = field.deconstruct()
self.assertEqual(path, "django.db.models.ForeignKey")
self.assertEqual(args, [])
self.assertEqual(kwargs, {"to": "auth.Permission"})
self.assertEqual(kwargs, {"to": "auth.Permission", "on_delete": models.CASCADE})
self.assertFalse(hasattr(kwargs['to'], "setting_name"))
# Test swap detection for swappable model
field = models.ForeignKey("auth.User")
field = models.ForeignKey("auth.User", models.CASCADE)
name, path, args, kwargs = field.deconstruct()
self.assertEqual(path, "django.db.models.ForeignKey")
self.assertEqual(args, [])
self.assertEqual(kwargs, {"to": "auth.User"})
self.assertEqual(kwargs, {"to": "auth.User", "on_delete": models.CASCADE})
self.assertEqual(kwargs['to'].setting_name, "AUTH_USER_MODEL")
# Test nonexistent (for now) model
field = models.ForeignKey("something.Else")
field = models.ForeignKey("something.Else", models.CASCADE)
name, path, args, kwargs = field.deconstruct()
self.assertEqual(path, "django.db.models.ForeignKey")
self.assertEqual(args, [])
self.assertEqual(kwargs, {"to": "something.Else"})
self.assertEqual(kwargs, {"to": "something.Else", "on_delete": models.CASCADE})
# Test on_delete
field = models.ForeignKey("auth.User", on_delete=models.SET_NULL)
field = models.ForeignKey("auth.User", models.SET_NULL)
name, path, args, kwargs = field.deconstruct()
self.assertEqual(path, "django.db.models.ForeignKey")
self.assertEqual(args, [])
self.assertEqual(kwargs, {"to": "auth.User", "on_delete": models.SET_NULL})
# Test to_field preservation
field = models.ForeignKey("auth.Permission", to_field="foobar")
field = models.ForeignKey("auth.Permission", models.CASCADE, to_field="foobar")
name, path, args, kwargs = field.deconstruct()
self.assertEqual(path, "django.db.models.ForeignKey")
self.assertEqual(args, [])
self.assertEqual(kwargs, {"to": "auth.Permission", "to_field": "foobar"})
self.assertEqual(kwargs, {"to": "auth.Permission", "to_field": "foobar", "on_delete": models.CASCADE})
# Test related_name preservation
field = models.ForeignKey("auth.Permission", related_name="foobar")
field = models.ForeignKey("auth.Permission", models.CASCADE, related_name="foobar")
name, path, args, kwargs = field.deconstruct()
self.assertEqual(path, "django.db.models.ForeignKey")
self.assertEqual(args, [])
self.assertEqual(kwargs, {"to": "auth.Permission", "related_name": "foobar"})
self.assertEqual(kwargs, {"to": "auth.Permission", "related_name": "foobar", "on_delete": models.CASCADE})
@override_settings(AUTH_USER_MODEL="auth.Permission")
def test_foreign_key_swapped(self):
# It doesn't matter that we swapped out user for permission;
# there's no validation. We just want to check the setting stuff works.
field = models.ForeignKey("auth.Permission")
field = models.ForeignKey("auth.Permission", models.CASCADE)
name, path, args, kwargs = field.deconstruct()
self.assertEqual(path, "django.db.models.ForeignKey")
self.assertEqual(args, [])
self.assertEqual(kwargs, {"to": "auth.Permission"})
self.assertEqual(kwargs, {"to": "auth.Permission", "on_delete": models.CASCADE})
self.assertEqual(kwargs['to'].setting_name, "AUTH_USER_MODEL")
def test_image_field(self):

View File

@ -42,7 +42,7 @@ class Article(models.Model):
@python_2_unicode_compatible
class Blog(models.Model):
name = models.CharField(max_length=100)
featured = models.ForeignKey(Article, related_name='fixtures_featured_set')
featured = models.ForeignKey(Article, models.CASCADE, related_name='fixtures_featured_set')
articles = models.ManyToManyField(Article, blank=True,
related_name='fixtures_articles_set')
@ -53,7 +53,7 @@ class Blog(models.Model):
@python_2_unicode_compatible
class Tag(models.Model):
name = models.CharField(max_length=100)
tagged_type = models.ForeignKey(ContentType, related_name="fixtures_tag_set")
tagged_type = models.ForeignKey(ContentType, models.CASCADE, related_name="fixtures_tag_set")
tagged_id = models.PositiveIntegerField(default=0)
tagged = GenericForeignKey(ct_field='tagged_type', fk_field='tagged_id')
@ -94,7 +94,7 @@ class Spy(Person):
@python_2_unicode_compatible
class Visa(models.Model):
person = models.ForeignKey(Person)
person = models.ForeignKey(Person, models.CASCADE)
permissions = models.ManyToManyField(Permission, blank=True)
def __str__(self):

View File

@ -31,7 +31,7 @@ class Plant(models.Model):
@python_2_unicode_compatible
class Stuff(models.Model):
name = models.CharField(max_length=20, null=True)
owner = models.ForeignKey(User, null=True)
owner = models.ForeignKey(User, models.SET_NULL, null=True)
def __str__(self):
return six.text_type(self.name) + ' is owned by ' + six.text_type(self.owner)
@ -108,7 +108,7 @@ class TestManager(models.Manager):
class Store(models.Model):
objects = TestManager()
name = models.CharField(max_length=255)
main = models.ForeignKey('self', null=True)
main = models.ForeignKey('self', models.SET_NULL, null=True)
class Meta:
ordering = ('name',)
@ -141,7 +141,7 @@ class Person(models.Model):
@python_2_unicode_compatible
class Book(models.Model):
name = models.CharField(max_length=255)
author = models.ForeignKey(Person)
author = models.ForeignKey(Person, models.CASCADE)
stores = models.ManyToManyField(Store)
class Meta:
@ -175,7 +175,7 @@ class NKChild(Parent):
@python_2_unicode_compatible
class RefToNKChild(models.Model):
text = models.CharField(max_length=10)
nk_fk = models.ForeignKey(NKChild, related_name='ref_fks')
nk_fk = models.ForeignKey(NKChild, models.CASCADE, related_name='ref_fks')
nk_m2m = models.ManyToManyField(NKChild, related_name='ref_m2ms')
def __str__(self):
@ -295,8 +295,8 @@ class M2MComplexB(BaseNKModel):
class M2MThroughAB(BaseNKModel):
a = models.ForeignKey(M2MComplexA)
b = models.ForeignKey(M2MComplexB)
a = models.ForeignKey(M2MComplexA, models.CASCADE)
b = models.ForeignKey(M2MComplexB, models.CASCADE)
class M2MComplexCircular1A(BaseNKModel):
@ -315,18 +315,18 @@ class M2MComplexCircular1C(BaseNKModel):
class M2MCircular1ThroughAB(BaseNKModel):
a = models.ForeignKey(M2MComplexCircular1A)
b = models.ForeignKey(M2MComplexCircular1B)
a = models.ForeignKey(M2MComplexCircular1A, models.CASCADE)
b = models.ForeignKey(M2MComplexCircular1B, models.CASCADE)
class M2MCircular1ThroughBC(BaseNKModel):
b = models.ForeignKey(M2MComplexCircular1B)
c = models.ForeignKey(M2MComplexCircular1C)
b = models.ForeignKey(M2MComplexCircular1B, models.CASCADE)
c = models.ForeignKey(M2MComplexCircular1C, models.CASCADE)
class M2MCircular1ThroughCA(BaseNKModel):
c = models.ForeignKey(M2MComplexCircular1C)
a = models.ForeignKey(M2MComplexCircular1A)
c = models.ForeignKey(M2MComplexCircular1C, models.CASCADE)
a = models.ForeignKey(M2MComplexCircular1A, models.CASCADE)
class M2MComplexCircular2A(BaseNKModel):
@ -342,5 +342,5 @@ class M2MComplexCircular2B(BaseNKModel):
class M2MCircular2ThroughAB(BaseNKModel):
a = models.ForeignKey(M2MComplexCircular2A)
b = models.ForeignKey(M2MComplexCircular2B)
a = models.ForeignKey(M2MComplexCircular2A, models.CASCADE)
b = models.ForeignKey(M2MComplexCircular2B, models.CASCADE)

View File

@ -24,7 +24,11 @@ class Person(models.Model):
# Relation Fields
person_country = models.ForeignObject(
Country, from_fields=['person_country_id'], to_fields=['id'])
Country,
from_fields=['person_country_id'],
to_fields=['id'],
on_delete=models.CASCADE,
)
friends = models.ManyToManyField('self', through='Friendship', symmetrical=False)
class Meta:
@ -38,7 +42,7 @@ class Person(models.Model):
class Group(models.Model):
# Table Column Fields
name = models.CharField(max_length=128)
group_country = models.ForeignKey(Country)
group_country = models.ForeignKey(Country, models.CASCADE)
members = models.ManyToManyField(Person, related_name='groups', through='Membership')
class Meta:
@ -51,7 +55,7 @@ class Group(models.Model):
@python_2_unicode_compatible
class Membership(models.Model):
# Table Column Fields
membership_country = models.ForeignKey(Country)
membership_country = models.ForeignKey(Country, models.CASCADE)
date_joined = models.DateTimeField(default=datetime.datetime.now)
invite_reason = models.CharField(max_length=64, null=True)
person_id = models.IntegerField()
@ -61,11 +65,15 @@ class Membership(models.Model):
person = models.ForeignObject(
Person,
from_fields=['membership_country', 'person_id'],
to_fields=['person_country_id', 'id'])
to_fields=['person_country_id', 'id'],
on_delete=models.CASCADE,
)
group = models.ForeignObject(
Group,
from_fields=['membership_country', 'group_id'],
to_fields=['group_country', 'id'])
to_fields=['group_country', 'id'],
on_delete=models.CASCADE,
)
class Meta:
ordering = ('date_joined', 'invite_reason')
@ -76,7 +84,7 @@ class Membership(models.Model):
class Friendship(models.Model):
# Table Column Fields
from_friend_country = models.ForeignKey(Country, related_name="from_friend_country")
from_friend_country = models.ForeignKey(Country, models.CASCADE, related_name="from_friend_country")
from_friend_id = models.IntegerField()
to_friend_country_id = models.IntegerField()
to_friend_id = models.IntegerField()
@ -84,6 +92,7 @@ class Friendship(models.Model):
# Relation Fields
from_friend = models.ForeignObject(
Person,
on_delete=models.CASCADE,
from_fields=['from_friend_country', 'from_friend_id'],
to_fields=['person_country_id', 'id'],
related_name='from_friend')
@ -92,13 +101,17 @@ class Friendship(models.Model):
Country,
from_fields=['to_friend_country_id'],
to_fields=['id'],
related_name='to_friend_country')
related_name='to_friend_country',
on_delete=models.CASCADE,
)
to_friend = models.ForeignObject(
Person,
from_fields=['to_friend_country_id', 'to_friend_id'],
to_fields=['person_country_id', 'id'],
related_name='to_friend')
related_name='to_friend',
on_delete=models.CASCADE,
)
class ArticleTranslationDescriptor(ReverseSingleRelatedObjectDescriptor):
@ -148,7 +161,9 @@ class Article(models.Model):
from_fields=['id'],
to_fields=['article'],
related_name='+',
null=True)
on_delete=models.CASCADE,
null=True,
)
pub_date = models.DateField()
def __str__(self):
@ -163,7 +178,7 @@ class NewsArticle(Article):
class ArticleTranslation(models.Model):
article = models.ForeignKey(Article)
article = models.ForeignKey(Article, models.CASCADE)
lang = models.CharField(max_length=2)
title = models.CharField(max_length=100)
body = models.TextField()
@ -175,7 +190,7 @@ class ArticleTranslation(models.Model):
class ArticleTag(models.Model):
article = models.ForeignKey(Article, related_name="tags", related_query_name="tag")
article = models.ForeignKey(Article, models.CASCADE, related_name="tags", related_query_name="tag")
name = models.CharField(max_length=255)

View File

@ -92,11 +92,13 @@ class ChoiceFieldModel(models.Model):
generation with ModelChoiceField."""
choice = models.ForeignKey(
ChoiceOptionModel,
models.CASCADE,
blank=False,
default=choice_default,
)
choice_int = models.ForeignKey(
ChoiceOptionModel,
models.CASCADE,
blank=False,
related_name='choice_int',
default=int_default,

View File

@ -228,7 +228,7 @@ class RelatedModelFormTests(SimpleTestCase):
Test for issue 10405
"""
class A(models.Model):
ref = models.ForeignKey("B")
ref = models.ForeignKey("B", models.CASCADE)
class Meta:
model = A
@ -244,7 +244,7 @@ class RelatedModelFormTests(SimpleTestCase):
Test for issue 10405
"""
class C(models.Model):
ref = models.ForeignKey("D")
ref = models.ForeignKey("D", models.CASCADE)
class D(models.Model):
pass

View File

@ -17,7 +17,7 @@ class Media(models.Model):
"""
Media that can associated to any object.
"""
content_type = models.ForeignKey(ContentType)
content_type = models.ForeignKey(ContentType, models.CASCADE)
object_id = models.PositiveIntegerField()
content_object = GenericForeignKey()
url = models.URLField()
@ -36,11 +36,11 @@ class Category(models.Model):
class PhoneNumber(models.Model):
content_type = models.ForeignKey(ContentType)
content_type = models.ForeignKey(ContentType, models.CASCADE)
object_id = models.PositiveIntegerField()
content_object = GenericForeignKey('content_type', 'object_id')
phone_number = models.CharField(max_length=30)
category = models.ForeignKey(Category, null=True, blank=True)
category = models.ForeignKey(Category, models.SET_NULL, null=True, blank=True)
class Meta:
unique_together = (('content_type', 'object_id', 'phone_number',),)

View File

@ -23,7 +23,7 @@ from django.utils.encoding import python_2_unicode_compatible
class TaggedItem(models.Model):
"""A tag on an item."""
tag = models.SlugField()
content_type = models.ForeignKey(ContentType)
content_type = models.ForeignKey(ContentType, models.CASCADE)
object_id = models.PositiveIntegerField()
content_object = GenericForeignKey()
@ -42,7 +42,7 @@ class ValuableTaggedItem(TaggedItem):
class AbstractComparison(models.Model):
comparative = models.CharField(max_length=50)
content_type1 = models.ForeignKey(ContentType, related_name="comparative1_set")
content_type1 = models.ForeignKey(ContentType, models.CASCADE, related_name="comparative1_set")
object_id1 = models.PositiveIntegerField()
first_obj = GenericForeignKey(ct_field="content_type1", fk_field="object_id1")
@ -54,7 +54,7 @@ class Comparison(AbstractComparison):
A model that tests having multiple GenericForeignKeys. One is defined
through an inherited abstract model and one defined directly on this class.
"""
content_type2 = models.ForeignKey(ContentType, related_name="comparative2_set")
content_type2 = models.ForeignKey(ContentType, models.CASCADE, related_name="comparative2_set")
object_id2 = models.PositiveIntegerField()
other_obj = GenericForeignKey(ct_field="content_type2", fk_field="object_id2")
@ -120,14 +120,14 @@ class ManualPK(models.Model):
class ForProxyModelModel(models.Model):
content_type = models.ForeignKey(ContentType)
content_type = models.ForeignKey(ContentType, models.CASCADE)
object_id = models.PositiveIntegerField()
obj = GenericForeignKey(for_concrete_model=False)
title = models.CharField(max_length=255, null=True)
class ForConcreteModelModel(models.Model):
content_type = models.ForeignKey(ContentType)
content_type = models.ForeignKey(ContentType, models.CASCADE)
object_id = models.PositiveIntegerField()
obj = GenericForeignKey()
@ -143,6 +143,6 @@ class ProxyRelatedModel(ConcreteRelatedModel):
# To test fix for #7551
class AllowsNullGFK(models.Model):
content_type = models.ForeignKey(ContentType, null=True)
content_type = models.ForeignKey(ContentType, models.SET_NULL, null=True)
object_id = models.PositiveIntegerField(null=True)
content_object = GenericForeignKey()

View File

@ -13,7 +13,7 @@ __all__ = ('Link', 'Place', 'Restaurant', 'Person', 'Address',
@python_2_unicode_compatible
class Link(models.Model):
content_type = models.ForeignKey(ContentType)
content_type = models.ForeignKey(ContentType, models.CASCADE)
object_id = models.PositiveIntegerField()
content_object = GenericForeignKey()
@ -42,7 +42,7 @@ class Address(models.Model):
city = models.CharField(max_length=50)
state = models.CharField(max_length=2)
zipcode = models.CharField(max_length=5)
content_type = models.ForeignKey(ContentType)
content_type = models.ForeignKey(ContentType, models.CASCADE)
object_id = models.PositiveIntegerField()
content_object = GenericForeignKey()
@ -61,13 +61,13 @@ class Person(models.Model):
class CharLink(models.Model):
content_type = models.ForeignKey(ContentType)
content_type = models.ForeignKey(ContentType, models.CASCADE)
object_id = models.CharField(max_length=100)
content_object = GenericForeignKey()
class TextLink(models.Model):
content_type = models.ForeignKey(ContentType)
content_type = models.ForeignKey(ContentType, models.CASCADE)
object_id = models.TextField()
content_object = GenericForeignKey()
@ -84,7 +84,7 @@ class OddRelation2(models.Model):
# models for test_q_object_or:
class Note(models.Model):
content_type = models.ForeignKey(ContentType)
content_type = models.ForeignKey(ContentType, models.CASCADE)
object_id = models.PositiveIntegerField()
content_object = GenericForeignKey()
note = models.TextField()
@ -135,7 +135,7 @@ class Guild(models.Model):
class Tag(models.Model):
content_type = models.ForeignKey(ContentType, related_name='g_r_r_tags')
content_type = models.ForeignKey(ContentType, models.CASCADE, related_name='g_r_r_tags')
object_id = models.CharField(max_length=15)
content_object = GenericForeignKey()
label = models.CharField(max_length=15)
@ -168,7 +168,7 @@ class HasLinkThing(HasLinks):
class A(models.Model):
flag = models.NullBooleanField()
content_type = models.ForeignKey(ContentType)
content_type = models.ForeignKey(ContentType, models.CASCADE)
object_id = models.PositiveIntegerField()
content_object = GenericForeignKey('content_type', 'object_id')
@ -181,14 +181,14 @@ class B(models.Model):
class C(models.Model):
b = models.ForeignKey(B)
b = models.ForeignKey(B, models.CASCADE)
class Meta:
ordering = ('id',)
class D(models.Model):
b = models.ForeignKey(B, null=True)
b = models.ForeignKey(B, models.SET_NULL, null=True)
class Meta:
ordering = ('id',)
@ -197,14 +197,14 @@ class D(models.Model):
# Ticket #22998
class Node(models.Model):
content_type = models.ForeignKey(ContentType)
content_type = models.ForeignKey(ContentType, models.CASCADE)
object_id = models.PositiveIntegerField()
content = GenericForeignKey('content_type', 'object_id')
class Content(models.Model):
nodes = GenericRelation(Node)
related_obj = models.ForeignKey('Related', on_delete=models.CASCADE)
related_obj = models.ForeignKey('Related', models.CASCADE)
class Related(models.Model):

View File

@ -25,7 +25,7 @@ class ManualPrimaryKeyTest(models.Model):
class Profile(models.Model):
person = models.ForeignKey(Person, primary_key=True)
person = models.ForeignKey(Person, models.CASCADE, primary_key=True)
class Tag(models.Model):
@ -48,4 +48,9 @@ class Author(models.Model):
class Book(models.Model):
name = models.CharField(max_length=100)
authors = models.ManyToManyField(Author, related_name='books')
publisher = models.ForeignKey(Publisher, related_name='books', db_column="publisher_id_column")
publisher = models.ForeignKey(
Publisher,
models.CASCADE,
related_name='books',
db_column="publisher_id_column",
)

View File

@ -57,7 +57,7 @@ class Track(NamedModel):
class MultiFields(NamedModel):
city = models.ForeignKey(City)
city = models.ForeignKey(City, models.CASCADE)
point = models.PointField()
poly = models.PolygonField()

View File

@ -19,7 +19,12 @@ ops = [
name='Household',
fields=[
('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
('neighborhood', models.ForeignKey(to='gis_migrations.Neighborhood', to_field='id', null=True)),
('neighborhood', models.ForeignKey(
'gis_migrations.Neighborhood',
models.SET_NULL,
to_field='id',
null=True,
)),
('address', models.CharField(max_length=100)),
('zip_code', models.IntegerField(null=True, blank=True)),
('geom', gis_models.PointField(srid=4326, geography=True)),
@ -42,7 +47,7 @@ ops = [
migrations.AddField(
model_name='household',
name='family',
field=models.ForeignKey(blank=True, to='gis_migrations.Family', null=True),
field=models.ForeignKey('gis_migrations.Family', models.SET_NULL, blank=True, null=True),
preserve_default=True,
)
]

View File

@ -22,7 +22,7 @@ class State(NamedModel):
class County(NamedModel):
state = models.ForeignKey(State)
state = models.ForeignKey(State, models.CASCADE)
mpoly = models.MultiPolygonField(srid=4269) # Multipolygon in NAD83

View File

@ -24,7 +24,7 @@ class Location(SimpleModel):
class City(SimpleModel):
name = models.CharField(max_length=50)
state = models.CharField(max_length=2)
location = models.ForeignKey(Location)
location = models.ForeignKey(Location, models.CASCADE)
def __str__(self):
return self.name
@ -38,13 +38,13 @@ class AugmentedLocation(Location):
class DirectoryEntry(SimpleModel):
listing_text = models.CharField(max_length=50)
location = models.ForeignKey(AugmentedLocation)
location = models.ForeignKey(AugmentedLocation, models.CASCADE)
@python_2_unicode_compatible
class Parcel(SimpleModel):
name = models.CharField(max_length=30)
city = models.ForeignKey(City)
city = models.ForeignKey(City, models.CASCADE)
center1 = models.PointField()
# Throwing a curveball w/`db_column` here.
center2 = models.PointField(srid=2276, db_column='mycenter')
@ -63,12 +63,12 @@ class Author(SimpleModel):
class Article(SimpleModel):
title = models.CharField(max_length=100)
author = models.ForeignKey(Author, unique=True)
author = models.ForeignKey(Author, models.CASCADE, unique=True)
class Book(SimpleModel):
title = models.CharField(max_length=100)
author = models.ForeignKey(Author, related_name='books', null=True)
author = models.ForeignKey(Author, models.SET_NULL, related_name='books', null=True)
class Event(SimpleModel):

View File

@ -8,17 +8,17 @@ class CurrentTranslation(models.ForeignObject):
# Avoid validation
requires_unique_target = False
def __init__(self, to, from_fields, to_fields, **kwargs):
def __init__(self, to, on_delete, from_fields, to_fields, **kwargs):
# Disable reverse relation
kwargs['related_name'] = '+'
# Set unique to enable model cache.
kwargs['unique'] = True
super(CurrentTranslation, self).__init__(to, from_fields, to_fields, **kwargs)
super(CurrentTranslation, self).__init__(to, on_delete, from_fields, to_fields, **kwargs)
class ArticleTranslation(models.Model):
article = models.ForeignKey('indexes.Article')
article = models.ForeignKey('indexes.Article', models.CASCADE)
language = models.CharField(max_length=10, unique=True)
content = models.TextField()
@ -28,7 +28,7 @@ class Article(models.Model):
pub_date = models.DateTimeField()
# Add virtual relation to the ArticleTranslation model.
translation = CurrentTranslation(ArticleTranslation, ['id'], ['article'])
translation = CurrentTranslation(ArticleTranslation, models.CASCADE, ['id'], ['article'])
class Meta:
index_together = [

View File

@ -12,9 +12,9 @@ class Parent(models.Model):
class Child(models.Model):
mother = models.ForeignKey(Parent, related_name='mothers_children')
father = models.ForeignKey(Parent, related_name='fathers_children')
school = models.ForeignKey(School)
mother = models.ForeignKey(Parent, models.CASCADE, related_name='mothers_children')
father = models.ForeignKey(Parent, models.CASCADE, related_name='fathers_children')
school = models.ForeignKey(School, models.CASCADE)
name = models.CharField(max_length=100)
@ -28,7 +28,7 @@ class Poet(models.Model):
@python_2_unicode_compatible
class Poem(models.Model):
poet = models.ForeignKey(Poet)
poet = models.ForeignKey(Poet, models.CASCADE)
name = models.CharField(max_length=100)
def __str__(self):

View File

@ -6,20 +6,20 @@ from django.db import models
class People(models.Model):
name = models.CharField(max_length=255)
parent = models.ForeignKey('self')
parent = models.ForeignKey('self', models.CASCADE)
class Message(models.Model):
from_field = models.ForeignKey(People, db_column='from_id')
from_field = models.ForeignKey(People, models.CASCADE, db_column='from_id')
class PeopleData(models.Model):
people_pk = models.ForeignKey(People, primary_key=True)
people_pk = models.ForeignKey(People, models.CASCADE, primary_key=True)
ssn = models.CharField(max_length=11)
class PeopleMoreData(models.Model):
people_unique = models.ForeignKey(People, unique=True)
people_unique = models.ForeignKey(People, models.CASCADE, unique=True)
license = models.CharField(max_length=255)

View File

@ -144,15 +144,25 @@ class InspectDBTestCase(TestCase):
output = out.getvalue()
error_message = "inspectdb generated an attribute name which is a python keyword"
# Recursive foreign keys should be set to 'self'
self.assertIn("parent = models.ForeignKey('self')", output)
self.assertNotIn("from = models.ForeignKey(InspectdbPeople)", output, msg=error_message)
self.assertIn("parent = models.ForeignKey('self', models.DO_NOTHING)", output)
self.assertNotIn(
"from = models.ForeignKey(InspectdbPeople, models.DO_NOTHING)",
output,
msg=error_message,
)
# As InspectdbPeople model is defined after InspectdbMessage, it should be quoted
self.assertIn("from_field = models.ForeignKey('InspectdbPeople', db_column='from_id')",
output)
self.assertIn("people_pk = models.ForeignKey(InspectdbPeople, primary_key=True)",
output)
self.assertIn("people_unique = models.ForeignKey(InspectdbPeople, unique=True)",
output)
self.assertIn(
"from_field = models.ForeignKey('InspectdbPeople', models.DO_NOTHING, db_column='from_id')",
output,
)
self.assertIn(
"people_pk = models.ForeignKey(InspectdbPeople, models.DO_NOTHING, primary_key=True)",
output,
)
self.assertIn(
"people_unique = models.ForeignKey(InspectdbPeople, models.DO_NOTHING, unique=True)",
output,
)
def test_digits_column_name_introspection(self):
"""Introspection of column names consist/start with digits (#16536/#17676)"""

View File

@ -25,8 +25,8 @@ class Article(models.Model):
headline = models.CharField(max_length=100)
pub_date = models.DateField()
body = models.TextField(default='')
reporter = models.ForeignKey(Reporter)
response_to = models.ForeignKey('self', null=True)
reporter = models.ForeignKey(Reporter, models.CASCADE)
response_to = models.ForeignKey('self', models.SET_NULL, null=True)
def __str__(self):
return self.headline

View File

@ -305,22 +305,28 @@ class FieldNamesTests(IsolatedModelsTestCase):
related_name="rn3",
through='m2mcomplex'
)
fk = models.ForeignKey(VeryLongModelNamezzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz, related_name="rn4")
fk = models.ForeignKey(
VeryLongModelNamezzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz,
models.CASCADE,
related_name="rn4",
)
# Models used for setting `through` in M2M field.
class m2msimple(models.Model):
id2 = models.ForeignKey(ModelWithLongField)
id2 = models.ForeignKey(ModelWithLongField, models.CASCADE)
class m2mcomplex(models.Model):
id2 = models.ForeignKey(ModelWithLongField)
id2 = models.ForeignKey(ModelWithLongField, models.CASCADE)
long_field_name = 'a' * (self.max_column_name_length + 1)
models.ForeignKey(
VeryLongModelNamezzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz
VeryLongModelNamezzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz,
models.CASCADE,
).contribute_to_class(m2msimple, long_field_name)
models.ForeignKey(
VeryLongModelNamezzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz,
models.CASCADE,
db_column=long_field_name
).contribute_to_class(m2mcomplex, long_field_name)
@ -473,7 +479,7 @@ class ShadowingFieldsTests(IsolatedModelsTestCase):
class Child(Parent):
# This field clashes with parent "f_id" field.
f = models.ForeignKey(Target)
f = models.ForeignKey(Target, models.CASCADE)
errors = Child.check()
expected = [
@ -517,7 +523,7 @@ class ShadowingFieldsTests(IsolatedModelsTestCase):
pass
class Model(models.Model):
fk = models.ForeignKey(Target)
fk = models.ForeignKey(Target, models.CASCADE)
fk_id = models.IntegerField()
errors = Model.check()
@ -584,7 +590,7 @@ class OtherModelTests(IsolatedModelsTestCase):
pass
class Answer(models.Model):
question = models.ForeignKey(Question)
question = models.ForeignKey(Question, models.CASCADE)
class Meta:
order_with_respect_to = 'question'
@ -596,7 +602,7 @@ class OtherModelTests(IsolatedModelsTestCase):
pass
class Answer(models.Model):
question = models.ForeignKey(Question)
question = models.ForeignKey(Question, models.CASCADE)
order = models.IntegerField()
class Meta:
@ -678,7 +684,7 @@ class OtherModelTests(IsolatedModelsTestCase):
pass
class Child(models.Model):
parent = models.ForeignKey(Parent)
parent = models.ForeignKey(Parent, models.CASCADE)
class Meta:
ordering = ("parent_id",)
@ -731,8 +737,8 @@ class OtherModelTests(IsolatedModelsTestCase):
related_name="secondary")
class Membership(models.Model):
person = models.ForeignKey(Person)
group = models.ForeignKey(Group)
person = models.ForeignKey(Person, models.CASCADE)
group = models.ForeignKey(Group, models.CASCADE)
errors = Group.check()
expected = [

View File

@ -1,11 +1,16 @@
# -*- encoding: utf-8 -*-
from __future__ import unicode_literals
import warnings
from django.core.checks import Error, Warning as DjangoWarning
from django.db import models
from django.test import ignore_warnings
from django.test.testcases import skipIfDBFeature
from django.test.utils import override_settings
from django.utils import six
from django.utils.deprecation import RemovedInDjango20Warning
from django.utils.version import get_docs_version
from .base import IsolatedModelsTestCase
@ -18,18 +23,100 @@ class RelativeFieldTests(IsolatedModelsTestCase):
model = models.IntegerField()
class Model(models.Model):
field = models.ForeignKey(Target, related_name='+')
field = models.ForeignKey(Target, models.CASCADE, related_name='+')
field = Model._meta.get_field('field')
errors = field.check()
self.assertEqual(errors, [])
@ignore_warnings(category=RemovedInDjango20Warning)
def test_valid_foreign_key_without_on_delete(self):
class Target(models.Model):
model = models.IntegerField()
class Model(models.Model):
field = models.ForeignKey(Target, related_name='+')
def test_foreign_key_without_on_delete_warning(self):
with warnings.catch_warnings(record=True) as warns:
warnings.simplefilter('always') # prevent warnings from appearing as errors
class Target(models.Model):
model = models.IntegerField()
class Model(models.Model):
field = models.ForeignKey(Target, related_name='+')
self.assertEqual(len(warns), 1)
self.assertEqual(
str(warns[0].message),
'on_delete will be a required arg for ForeignKey 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' % get_docs_version(),
)
def test_foreign_key_to_field_as_arg(self):
with warnings.catch_warnings(record=True) as warns:
warnings.simplefilter('always') # prevent warnings from appearing as errors
class Target(models.Model):
model = models.IntegerField()
class Model(models.Model):
field = models.ForeignKey(Target, 'id')
self.assertEqual(len(warns), 1)
self.assertEqual(
str(warns[0].message),
"The signature for ForeignKey will change in Django 2.0. "
"Pass to_field='id' as a kwarg instead of as an arg."
)
def test_one_to_one_field_without_on_delete_warning(self):
with warnings.catch_warnings(record=True) as warns:
warnings.simplefilter('always') # prevent warnings from appearing as errors
class Target(models.Model):
model = models.IntegerField()
class Model(models.Model):
field = models.OneToOneField(Target, related_name='+')
self.assertEqual(len(warns), 1)
self.assertEqual(
str(warns[0].message),
'on_delete will be a required arg for OneToOneField 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' % get_docs_version(),
)
def test_one_to_one_field_to_field_as_arg(self):
with warnings.catch_warnings(record=True) as warns:
warnings.simplefilter('always') # prevent warnings from appearing as errors
class Target(models.Model):
model = models.IntegerField()
class Model(models.Model):
field = models.OneToOneField(Target, 'id')
self.assertEqual(len(warns), 1)
self.assertEqual(
str(warns[0].message),
"The signature for OneToOneField will change in Django 2.0. "
"Pass to_field='id' as a kwarg instead of as an arg."
)
def test_foreign_key_to_missing_model(self):
# Model names are resolved when a model is being created, so we cannot
# test relative fields in isolation and we need to attach them to a
# model.
class Model(models.Model):
foreign_key = models.ForeignKey('Rel1')
foreign_key = models.ForeignKey('Rel1', models.CASCADE)
field = Model._meta.get_field('foreign_key')
errors = field.check()
@ -101,9 +188,9 @@ class RelativeFieldTests(IsolatedModelsTestCase):
class AmbiguousRelationship(models.Model):
# Too much foreign keys to Person.
first_person = models.ForeignKey(Person, related_name="first")
second_person = models.ForeignKey(Person, related_name="second")
second_model = models.ForeignKey(Group)
first_person = models.ForeignKey(Person, models.CASCADE, related_name="first")
second_person = models.ForeignKey(Person, models.CASCADE, related_name="second")
second_model = models.ForeignKey(Group, models.CASCADE)
field = Group._meta.get_field('field')
errors = field.check(from_model=Group)
@ -135,8 +222,8 @@ class RelativeFieldTests(IsolatedModelsTestCase):
through="InvalidRelationship")
class InvalidRelationship(models.Model):
person = models.ForeignKey(Person)
wrong_foreign_key = models.ForeignKey(WrongModel)
person = models.ForeignKey(Person, models.CASCADE)
wrong_foreign_key = models.ForeignKey(WrongModel, models.CASCADE)
# The last foreign key should point to Group model.
field = Group._meta.get_field('members')
@ -162,7 +249,7 @@ class RelativeFieldTests(IsolatedModelsTestCase):
through="InvalidRelationship")
class InvalidRelationship(models.Model):
group = models.ForeignKey(Group)
group = models.ForeignKey(Group, models.CASCADE)
# No foreign key to Person
field = Group._meta.get_field('members')
@ -206,8 +293,8 @@ class RelativeFieldTests(IsolatedModelsTestCase):
friends = models.ManyToManyField('self', through="Relationship")
class Relationship(models.Model):
first = models.ForeignKey(Person, related_name="rel_from_set")
second = models.ForeignKey(Person, related_name="rel_to_set")
first = models.ForeignKey(Person, models.CASCADE, related_name="rel_from_set")
second = models.ForeignKey(Person, models.CASCADE, related_name="rel_to_set")
field = Person._meta.get_field('friends')
errors = field.check(from_model=Person)
@ -227,9 +314,9 @@ class RelativeFieldTests(IsolatedModelsTestCase):
through="InvalidRelationship", symmetrical=False)
class InvalidRelationship(models.Model):
first = models.ForeignKey(Person, related_name="rel_from_set_2")
second = models.ForeignKey(Person, related_name="rel_to_set_2")
third = models.ForeignKey(Person, related_name="too_many_by_far")
first = models.ForeignKey(Person, models.CASCADE, related_name="rel_from_set_2")
second = models.ForeignKey(Person, models.CASCADE, related_name="rel_to_set_2")
third = models.ForeignKey(Person, models.CASCADE, related_name="too_many_by_far")
field = Person._meta.get_field('friends')
errors = field.check(from_model=Person)
@ -254,8 +341,8 @@ class RelativeFieldTests(IsolatedModelsTestCase):
through="Relationship", symmetrical=True)
class Relationship(models.Model):
first = models.ForeignKey(Person, related_name="rel_from_set")
second = models.ForeignKey(Person, related_name="rel_to_set")
first = models.ForeignKey(Person, models.CASCADE, related_name="rel_from_set")
second = models.ForeignKey(Person, models.CASCADE, related_name="rel_to_set")
field = Person._meta.get_field('friends')
errors = field.check(from_model=Person)
@ -279,9 +366,9 @@ class RelativeFieldTests(IsolatedModelsTestCase):
through_fields=('first', 'second'))
class Relationship(models.Model):
first = models.ForeignKey(Person, related_name="rel_from_set")
second = models.ForeignKey(Person, related_name="rel_to_set")
referee = models.ForeignKey(Person, related_name="referred")
first = models.ForeignKey(Person, models.CASCADE, related_name="rel_from_set")
second = models.ForeignKey(Person, models.CASCADE, related_name="rel_to_set")
referee = models.ForeignKey(Person, models.CASCADE, related_name="referred")
field = Person._meta.get_field('friends')
errors = field.check(from_model=Person)
@ -297,7 +384,7 @@ class RelativeFieldTests(IsolatedModelsTestCase):
def test_foreign_key_to_abstract_model(self):
class Model(models.Model):
foreign_key = models.ForeignKey('AbstractModel')
foreign_key = models.ForeignKey('AbstractModel', models.CASCADE)
class AbstractModel(models.Model):
class Meta:
@ -361,7 +448,7 @@ class RelativeFieldTests(IsolatedModelsTestCase):
bad = models.IntegerField() # No unique=True
class Model(models.Model):
foreign_key = models.ForeignKey('Target', to_field='bad')
foreign_key = models.ForeignKey('Target', models.CASCADE, to_field='bad')
field = Model._meta.get_field('foreign_key')
errors = field.check()
@ -380,7 +467,7 @@ class RelativeFieldTests(IsolatedModelsTestCase):
bad = models.IntegerField()
class Model(models.Model):
field = models.ForeignKey(Target, to_field='bad')
field = models.ForeignKey(Target, models.CASCADE, to_field='bad')
field = Model._meta.get_field('field')
errors = field.check()
@ -405,6 +492,7 @@ class RelativeFieldTests(IsolatedModelsTestCase):
person_city_id = models.IntegerField()
person = models.ForeignObject(Person,
on_delete=models.CASCADE,
from_fields=['person_country_id', 'person_city_id'],
to_fields=['country_id', 'city_id'])
@ -426,8 +514,7 @@ class RelativeFieldTests(IsolatedModelsTestCase):
pass
class Model(models.Model):
foreign_key = models.ForeignKey('Person',
on_delete=models.SET_NULL)
foreign_key = models.ForeignKey('Person', models.SET_NULL)
field = Model._meta.get_field('foreign_key')
errors = field.check()
@ -446,8 +533,7 @@ class RelativeFieldTests(IsolatedModelsTestCase):
pass
class Model(models.Model):
foreign_key = models.ForeignKey('Person',
on_delete=models.SET_DEFAULT)
foreign_key = models.ForeignKey('Person', models.SET_DEFAULT)
field = Model._meta.get_field('foreign_key')
errors = field.check()
@ -487,8 +573,10 @@ class RelativeFieldTests(IsolatedModelsTestCase):
class Model(models.Model):
explicit_fk = models.ForeignKey(SwappableModel,
models.CASCADE,
related_name='explicit_fk')
implicit_fk = models.ForeignKey('invalid_models_tests.SwappableModel',
models.CASCADE,
related_name='implicit_fk')
explicit_m2m = models.ManyToManyField(SwappableModel,
related_name='explicit_m2m')
@ -519,8 +607,10 @@ class RelativeFieldTests(IsolatedModelsTestCase):
class Model(models.Model):
explicit_fk = models.ForeignKey(SwappedModel,
models.CASCADE,
related_name='explicit_fk')
implicit_fk = models.ForeignKey('invalid_models_tests.SwappedModel',
models.CASCADE,
related_name='implicit_fk')
explicit_m2m = models.ManyToManyField(SwappedModel,
related_name='explicit_m2m')
@ -572,7 +662,7 @@ class RelativeFieldTests(IsolatedModelsTestCase):
for invalid_related_name in invalid_related_names:
Child = type(str('Child_%s') % str(invalid_related_name), (models.Model,), {
'parent': models.ForeignKey('Parent', related_name=invalid_related_name),
'parent': models.ForeignKey('Parent', models.CASCADE, related_name=invalid_related_name),
'__module__': Parent.__module__,
})
@ -613,7 +703,7 @@ class RelativeFieldTests(IsolatedModelsTestCase):
for related_name in related_names:
Child = type(str('Child_%s') % str(related_name), (models.Model,), {
'parent': models.ForeignKey('Parent', related_name=related_name),
'parent': models.ForeignKey('Parent', models.CASCADE, related_name=related_name),
'__module__': Parent.__module__,
})
@ -626,17 +716,17 @@ class AccessorClashTests(IsolatedModelsTestCase):
def test_fk_to_integer(self):
self._test_accessor_clash(
target=models.IntegerField(),
relative=models.ForeignKey('Target'))
relative=models.ForeignKey('Target', models.CASCADE))
def test_fk_to_fk(self):
self._test_accessor_clash(
target=models.ForeignKey('Another'),
relative=models.ForeignKey('Target'))
target=models.ForeignKey('Another', models.CASCADE),
relative=models.ForeignKey('Target', models.CASCADE))
def test_fk_to_m2m(self):
self._test_accessor_clash(
target=models.ManyToManyField('Another'),
relative=models.ForeignKey('Target'))
relative=models.ForeignKey('Target', models.CASCADE))
def test_m2m_to_integer(self):
self._test_accessor_clash(
@ -645,7 +735,7 @@ class AccessorClashTests(IsolatedModelsTestCase):
def test_m2m_to_fk(self):
self._test_accessor_clash(
target=models.ForeignKey('Another'),
target=models.ForeignKey('Another', models.CASCADE),
relative=models.ManyToManyField('Target'))
def test_m2m_to_m2m(self):
@ -681,7 +771,7 @@ class AccessorClashTests(IsolatedModelsTestCase):
pass
class Model(models.Model):
foreign = models.ForeignKey(Target)
foreign = models.ForeignKey(Target, models.CASCADE)
m2m = models.ManyToManyField(Target)
errors = Model.check()
@ -738,17 +828,17 @@ class ReverseQueryNameClashTests(IsolatedModelsTestCase):
def test_fk_to_integer(self):
self._test_reverse_query_name_clash(
target=models.IntegerField(),
relative=models.ForeignKey('Target'))
relative=models.ForeignKey('Target', models.CASCADE))
def test_fk_to_fk(self):
self._test_reverse_query_name_clash(
target=models.ForeignKey('Another'),
relative=models.ForeignKey('Target'))
target=models.ForeignKey('Another', models.CASCADE),
relative=models.ForeignKey('Target', models.CASCADE))
def test_fk_to_m2m(self):
self._test_reverse_query_name_clash(
target=models.ManyToManyField('Another'),
relative=models.ForeignKey('Target'))
relative=models.ForeignKey('Target', models.CASCADE))
def test_m2m_to_integer(self):
self._test_reverse_query_name_clash(
@ -757,7 +847,7 @@ class ReverseQueryNameClashTests(IsolatedModelsTestCase):
def test_m2m_to_fk(self):
self._test_reverse_query_name_clash(
target=models.ForeignKey('Another'),
target=models.ForeignKey('Another', models.CASCADE),
relative=models.ManyToManyField('Target'))
def test_m2m_to_m2m(self):
@ -794,17 +884,17 @@ class ExplicitRelatedNameClashTests(IsolatedModelsTestCase):
def test_fk_to_integer(self):
self._test_explicit_related_name_clash(
target=models.IntegerField(),
relative=models.ForeignKey('Target', related_name='clash'))
relative=models.ForeignKey('Target', models.CASCADE, related_name='clash'))
def test_fk_to_fk(self):
self._test_explicit_related_name_clash(
target=models.ForeignKey('Another'),
relative=models.ForeignKey('Target', related_name='clash'))
target=models.ForeignKey('Another', models.CASCADE),
relative=models.ForeignKey('Target', models.CASCADE, related_name='clash'))
def test_fk_to_m2m(self):
self._test_explicit_related_name_clash(
target=models.ManyToManyField('Another'),
relative=models.ForeignKey('Target', related_name='clash'))
relative=models.ForeignKey('Target', models.CASCADE, related_name='clash'))
def test_m2m_to_integer(self):
self._test_explicit_related_name_clash(
@ -813,7 +903,7 @@ class ExplicitRelatedNameClashTests(IsolatedModelsTestCase):
def test_m2m_to_fk(self):
self._test_explicit_related_name_clash(
target=models.ForeignKey('Another'),
target=models.ForeignKey('Another', models.CASCADE),
relative=models.ManyToManyField('Target', related_name='clash'))
def test_m2m_to_m2m(self):
@ -859,18 +949,21 @@ class ExplicitRelatedQueryNameClashTests(IsolatedModelsTestCase):
self._test_explicit_related_query_name_clash(
target=models.IntegerField(),
relative=models.ForeignKey('Target',
models.CASCADE,
related_query_name='clash'))
def test_fk_to_fk(self):
self._test_explicit_related_query_name_clash(
target=models.ForeignKey('Another'),
target=models.ForeignKey('Another', models.CASCADE),
relative=models.ForeignKey('Target',
models.CASCADE,
related_query_name='clash'))
def test_fk_to_m2m(self):
self._test_explicit_related_query_name_clash(
target=models.ManyToManyField('Another'),
relative=models.ForeignKey('Target',
models.CASCADE,
related_query_name='clash'))
def test_m2m_to_integer(self):
@ -881,7 +974,7 @@ class ExplicitRelatedQueryNameClashTests(IsolatedModelsTestCase):
def test_m2m_to_fk(self):
self._test_explicit_related_query_name_clash(
target=models.ForeignKey('Another'),
target=models.ForeignKey('Another', models.CASCADE),
relative=models.ManyToManyField('Target',
related_query_name='clash'))
@ -1013,7 +1106,7 @@ class SelfReferentialFKClashTests(IsolatedModelsTestCase):
def test_accessor_clash(self):
class Model(models.Model):
model_set = models.ForeignKey("Model")
model_set = models.ForeignKey("Model", models.CASCADE)
errors = Model.check()
expected = [
@ -1030,7 +1123,7 @@ class SelfReferentialFKClashTests(IsolatedModelsTestCase):
def test_reverse_query_name_clash(self):
class Model(models.Model):
model = models.ForeignKey("Model")
model = models.ForeignKey("Model", models.CASCADE)
errors = Model.check()
expected = [
@ -1048,7 +1141,7 @@ class SelfReferentialFKClashTests(IsolatedModelsTestCase):
def test_clash_under_explicit_related_name(self):
class Model(models.Model):
clash = models.CharField(max_length=10)
foreign = models.ForeignKey("Model", related_name='clash')
foreign = models.ForeignKey("Model", models.CASCADE, related_name='clash')
errors = Model.check()
expected = [
@ -1087,8 +1180,8 @@ class ComplexClashTests(IsolatedModelsTestCase):
class Model(models.Model):
src_safe = models.CharField(max_length=10)
foreign_1 = models.ForeignKey(Target, related_name='id')
foreign_2 = models.ForeignKey(Target, related_name='src_safe')
foreign_1 = models.ForeignKey(Target, models.CASCADE, related_name='id')
foreign_2 = models.ForeignKey(Target, models.CASCADE, related_name='src_safe')
m2m_1 = models.ManyToManyField(Target, related_name='id')
m2m_2 = models.ManyToManyField(Target, related_name='src_safe')
@ -1211,9 +1304,9 @@ class M2mThroughFieldsTests(IsolatedModelsTestCase):
invitees = models.ManyToManyField(Fan, through='Invitation', through_fields=('invitee', 'event'))
class Invitation(models.Model):
event = models.ForeignKey(Event)
invitee = models.ForeignKey(Fan)
inviter = models.ForeignKey(Fan, related_name='+')
event = models.ForeignKey(Event, models.CASCADE)
invitee = models.ForeignKey(Fan, models.CASCADE)
inviter = models.ForeignKey(Fan, models.CASCADE, related_name='+')
field = Event._meta.get_field('invitees')
errors = field.check(from_model=Event)
@ -1243,9 +1336,9 @@ class M2mThroughFieldsTests(IsolatedModelsTestCase):
invitees = models.ManyToManyField(Fan, through='Invitation', through_fields=('invalid_field_1', 'invalid_field_2'))
class Invitation(models.Model):
event = models.ForeignKey(Event)
invitee = models.ForeignKey(Fan)
inviter = models.ForeignKey(Fan, related_name='+')
event = models.ForeignKey(Event, models.CASCADE)
invitee = models.ForeignKey(Fan, models.CASCADE)
inviter = models.ForeignKey(Fan, models.CASCADE, related_name='+')
field = Event._meta.get_field('invitees')
errors = field.check(from_model=Event)
@ -1275,9 +1368,9 @@ class M2mThroughFieldsTests(IsolatedModelsTestCase):
invitees = models.ManyToManyField(Fan, through='Invitation', through_fields=(None, 'invitee'))
class Invitation(models.Model):
event = models.ForeignKey(Event)
invitee = models.ForeignKey(Fan)
inviter = models.ForeignKey(Fan, related_name='+')
event = models.ForeignKey(Event, models.CASCADE)
invitee = models.ForeignKey(Fan, models.CASCADE)
inviter = models.ForeignKey(Fan, models.CASCADE, related_name='+')
field = Event._meta.get_field('invitees')
errors = field.check(from_model=Event)

View File

@ -17,10 +17,10 @@ class Organiser(models.Model):
class Pool(models.Model):
name = models.CharField(max_length=30)
tournament = models.ForeignKey(Tournament)
organiser = models.ForeignKey(Organiser)
tournament = models.ForeignKey(Tournament, models.CASCADE)
organiser = models.ForeignKey(Organiser, models.CASCADE)
class PoolStyle(models.Model):
name = models.CharField(max_length=30)
pool = models.OneToOneField(Pool)
pool = models.OneToOneField(Pool, models.CASCADE)

View File

@ -30,7 +30,7 @@ class Author(models.Model):
class Article(models.Model):
headline = models.CharField(max_length=100)
pub_date = models.DateTimeField()
author = models.ForeignKey(Author, blank=True, null=True)
author = models.ForeignKey(Author, models.SET_NULL, blank=True, null=True)
class Meta:
ordering = ('-pub_date', 'headline')
@ -58,7 +58,7 @@ class Season(models.Model):
@python_2_unicode_compatible
class Game(models.Model):
season = models.ForeignKey(Season, related_name='games')
season = models.ForeignKey(Season, models.CASCADE, related_name='games')
home = models.CharField(max_length=100)
away = models.CharField(max_length=100)

View File

@ -18,7 +18,7 @@ class User(models.Model):
class Issue(models.Model):
num = models.IntegerField()
cc = models.ManyToManyField(User, blank=True, related_name='test_issue_cc')
client = models.ForeignKey(User, related_name='test_issue_client')
client = models.ForeignKey(User, models.CASCADE, related_name='test_issue_client')
def __str__(self):
return six.text_type(self.num)

View File

@ -35,8 +35,8 @@ class Article(models.Model):
@python_2_unicode_compatible
class Writer(models.Model):
reporter = models.ForeignKey(Reporter)
article = models.ForeignKey(Article)
reporter = models.ForeignKey(Reporter, models.CASCADE)
article = models.ForeignKey(Article, models.CASCADE)
position = models.CharField(max_length=100)
def __str__(self):

View File

@ -32,8 +32,8 @@ class Group(models.Model):
@python_2_unicode_compatible
class Membership(models.Model):
person = models.ForeignKey(Person)
group = models.ForeignKey(Group)
person = models.ForeignKey(Person, models.CASCADE)
group = models.ForeignKey(Group, models.CASCADE)
date_joined = models.DateTimeField(default=datetime.now)
invite_reason = models.CharField(max_length=64, null=True)
@ -46,9 +46,14 @@ class Membership(models.Model):
@python_2_unicode_compatible
class CustomMembership(models.Model):
person = models.ForeignKey(Person, db_column="custom_person_column", related_name="custom_person_related_name")
group = models.ForeignKey(Group)
weird_fk = models.ForeignKey(Membership, null=True)
person = models.ForeignKey(
Person,
models.CASCADE,
db_column="custom_person_column",
related_name="custom_person_related_name",
)
group = models.ForeignKey(Group, models.CASCADE)
weird_fk = models.ForeignKey(Membership, models.SET_NULL, null=True)
date_joined = models.DateTimeField(default=datetime.now)
def __str__(self):
@ -59,8 +64,8 @@ class CustomMembership(models.Model):
class TestNoDefaultsOrNulls(models.Model):
person = models.ForeignKey(Person)
group = models.ForeignKey(Group)
person = models.ForeignKey(Person, models.CASCADE)
group = models.ForeignKey(Group, models.CASCADE)
nodefaultnonull = models.CharField(max_length=5)
@ -74,8 +79,8 @@ class PersonSelfRefM2M(models.Model):
class Friendship(models.Model):
first = models.ForeignKey(PersonSelfRefM2M, related_name="rel_from_set")
second = models.ForeignKey(PersonSelfRefM2M, related_name="rel_to_set")
first = models.ForeignKey(PersonSelfRefM2M, models.CASCADE, related_name="rel_from_set")
second = models.ForeignKey(PersonSelfRefM2M, models.CASCADE, related_name="rel_to_set")
date_friended = models.DateTimeField()
@ -90,10 +95,10 @@ class Event(models.Model):
class Invitation(models.Model):
event = models.ForeignKey(Event, related_name='invitations')
event = models.ForeignKey(Event, models.CASCADE, related_name='invitations')
# field order is deliberately inverted. the target field is "invitee".
inviter = models.ForeignKey(Person, related_name='invitations_sent')
invitee = models.ForeignKey(Person, related_name='invitations')
inviter = models.ForeignKey(Person, models.CASCADE, related_name='invitations_sent')
invitee = models.ForeignKey(Person, models.CASCADE, related_name='invitations')
@python_2_unicode_compatible
@ -110,9 +115,9 @@ class Employee(models.Model):
class Relationship(models.Model):
# field order is deliberately inverted.
another = models.ForeignKey(Employee, related_name="rel_another_set", null=True)
target = models.ForeignKey(Employee, related_name="rel_target_set")
source = models.ForeignKey(Employee, related_name="rel_source_set")
another = models.ForeignKey(Employee, models.SET_NULL, related_name="rel_another_set", null=True)
target = models.ForeignKey(Employee, models.CASCADE, related_name="rel_target_set")
source = models.ForeignKey(Employee, models.CASCADE, related_name="rel_source_set")
class Ingredient(models.Model):
@ -133,5 +138,5 @@ class Recipe(models.Model):
class RecipeIngredient(models.Model):
ingredient = models.ForeignKey(Ingredient, to_field='iname')
recipe = models.ForeignKey(Recipe, to_field='rname')
ingredient = models.ForeignKey(Ingredient, models.CASCADE, to_field='iname')
recipe = models.ForeignKey(Recipe, models.CASCADE, to_field='rname')

View File

@ -8,8 +8,8 @@ from django.utils.encoding import python_2_unicode_compatible
# Forward declared intermediate model
@python_2_unicode_compatible
class Membership(models.Model):
person = models.ForeignKey('Person')
group = models.ForeignKey('Group')
person = models.ForeignKey('Person', models.CASCADE)
group = models.ForeignKey('Group', models.CASCADE)
price = models.IntegerField(default=100)
def __str__(self):
@ -20,8 +20,8 @@ class Membership(models.Model):
@python_2_unicode_compatible
class UserMembership(models.Model):
id = models.AutoField(db_column='usermembership_id', primary_key=True)
user = models.ForeignKey(User)
group = models.ForeignKey('Group')
user = models.ForeignKey(User, models.CASCADE)
group = models.ForeignKey('Group', models.CASCADE)
price = models.IntegerField(default=100)
def __str__(self):
@ -53,8 +53,8 @@ class A(models.Model):
class ThroughBase(models.Model):
a = models.ForeignKey(A)
b = models.ForeignKey('B')
a = models.ForeignKey(A, models.CASCADE)
b = models.ForeignKey('B', models.CASCADE)
class Through(ThroughBase):
@ -89,8 +89,8 @@ class Driver(models.Model):
@python_2_unicode_compatible
class CarDriver(models.Model):
car = models.ForeignKey('Car', to_field='make')
driver = models.ForeignKey('Driver', to_field='name')
car = models.ForeignKey('Car', models.CASCADE, to_field='make')
driver = models.ForeignKey('Driver', models.CASCADE, to_field='name')
def __str__(self):
return "pk=%s car=%s driver=%s" % (str(self.pk), self.car, self.driver)

View File

@ -2,7 +2,7 @@
Relating an object to itself, many-to-one
To define a many-to-one relationship between a model and itself, use
``ForeignKey('self')``.
``ForeignKey('self', ...)``.
In this example, a ``Category`` is related to itself. That is, each
``Category`` has a parent ``Category``.
@ -17,7 +17,7 @@ from django.utils.encoding import python_2_unicode_compatible
@python_2_unicode_compatible
class Category(models.Model):
name = models.CharField(max_length=20)
parent = models.ForeignKey('self', blank=True, null=True, related_name='child_set')
parent = models.ForeignKey('self', models.SET_NULL, blank=True, null=True, related_name='child_set')
def __str__(self):
return self.name
@ -26,8 +26,8 @@ class Category(models.Model):
@python_2_unicode_compatible
class Person(models.Model):
full_name = models.CharField(max_length=20)
mother = models.ForeignKey('self', null=True, related_name='mothers_child_set')
father = models.ForeignKey('self', null=True, related_name='fathers_child_set')
mother = models.ForeignKey('self', models.SET_NULL, null=True, related_name='mothers_child_set')
father = models.ForeignKey('self', models.SET_NULL, null=True, related_name='fathers_child_set')
def __str__(self):
return self.full_name

View File

@ -137,11 +137,11 @@ class RelatedModel(models.Model):
@python_2_unicode_compatible
class RelationModel(models.Model):
fk = models.ForeignKey(RelatedModel, related_name='test_fk')
fk = models.ForeignKey(RelatedModel, models.CASCADE, related_name='test_fk')
m2m = models.ManyToManyField(RelatedModel, related_name='test_m2m')
gfk_ctype = models.ForeignKey(ContentType, null=True)
gfk_ctype = models.ForeignKey(ContentType, models.SET_NULL, null=True)
gfk_id = models.IntegerField(null=True)
gfk = GenericForeignKey(ct_field='gfk_ctype', fk_field='gfk_id')

View File

@ -23,7 +23,7 @@ class Reporter(models.Model):
class Article(models.Model):
headline = models.CharField(max_length=100)
pub_date = models.DateField()
reporter = models.ForeignKey(Reporter)
reporter = models.ForeignKey(Reporter, models.CASCADE)
def __str__(self):
return self.headline
@ -40,27 +40,27 @@ class First(models.Model):
class Second(models.Model):
first = models.ForeignKey(First, related_name='the_first')
first = models.ForeignKey(First, models.CASCADE, related_name='the_first')
# Protect against repetition of #1839, #2415 and #2536.
class Third(models.Model):
name = models.CharField(max_length=20)
third = models.ForeignKey('self', null=True, related_name='child_set')
third = models.ForeignKey('self', models.SET_NULL, null=True, related_name='child_set')
class Parent(models.Model):
name = models.CharField(max_length=20, unique=True)
bestchild = models.ForeignKey('Child', null=True, related_name='favored_by')
bestchild = models.ForeignKey('Child', models.SET_NULL, null=True, related_name='favored_by')
class Child(models.Model):
name = models.CharField(max_length=20)
parent = models.ForeignKey(Parent)
parent = models.ForeignKey(Parent, models.CASCADE)
class ToFieldChild(models.Model):
parent = models.ForeignKey(Parent, to_field='name')
parent = models.ForeignKey(Parent, models.CASCADE, to_field='name')
# Multiple paths to the same model (#7110, #7125)
@ -73,13 +73,13 @@ class Category(models.Model):
class Record(models.Model):
category = models.ForeignKey(Category)
category = models.ForeignKey(Category, models.CASCADE)
@python_2_unicode_compatible
class Relation(models.Model):
left = models.ForeignKey(Record, related_name='left_set')
right = models.ForeignKey(Record, related_name='right_set')
left = models.ForeignKey(Record, models.CASCADE, related_name='left_set')
right = models.ForeignKey(Record, models.CASCADE, related_name='right_set')
def __str__(self):
return "%s - %s" % (self.left.category.name, self.right.category.name)
@ -97,4 +97,4 @@ class School(models.Model):
class Student(models.Model):
school = models.ForeignKey(School)
school = models.ForeignKey(School, models.CASCADE)

View File

@ -173,7 +173,7 @@ class ManyToOneTests(TestCase):
name = models.CharField(max_length=50)
class BandMember(models.Model):
band = UnsavedForeignKey(Band)
band = UnsavedForeignKey(Band, models.CASCADE)
first_name = models.CharField(max_length=50)
last_name = models.CharField(max_length=50)
@ -609,7 +609,7 @@ class ManyToOneTests(TestCase):
def test_fk_instantiation_outside_model(self):
# Regression for #12190 -- Should be able to instantiate a FK outside
# of a model, and interrogate its related field.
cat = models.ForeignKey(Category)
cat = models.ForeignKey(Category, models.CASCADE)
self.assertEqual('id', cat.remote_field.get_related_field().name)
def test_relation_unsaved(self):

Some files were not shown because too many files have changed in this diff Show More