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')), ('object_repr', models.CharField(max_length=200, verbose_name='object repr')),
('action_flag', models.PositiveSmallIntegerField(verbose_name='action flag')), ('action_flag', models.PositiveSmallIntegerField(verbose_name='action flag')),
('change_message', models.TextField(verbose_name='change message', blank=True)), ('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')), ('content_type', models.ForeignKey(
('user', models.ForeignKey(to=settings.AUTH_USER_MODEL, verbose_name='user')), 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={ options={
'ordering': ('-action_time',), 'ordering': ('-action_time',),

View File

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

View File

@ -19,7 +19,12 @@ class Migration(migrations.Migration):
fields=[ fields=[
('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)), ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
('name', models.CharField(max_length=50, verbose_name='name')), ('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')), ('codename', models.CharField(max_length=100, verbose_name='codename')),
], ],
options={ options={

View File

@ -59,7 +59,11 @@ class Permission(models.Model):
created for each Django model. created for each Django model.
""" """
name = models.CharField(_('name'), max_length=255) 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) codename = models.CharField(_('codename'), max_length=100)
objects = PermissionManager() objects = PermissionManager()

View File

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

View File

@ -15,7 +15,12 @@ class Migration(migrations.Migration):
name='Redirect', name='Redirect',
fields=[ fields=[
('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)), ('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)), ('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)), ('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 @python_2_unicode_compatible
class Redirect(models.Model): 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, 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/'.")) 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, 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 "# You'll have to do the following manually to clean this up:"
yield "# * Rearrange models' order" yield "# * Rearrange models' order"
yield "# * Make sure each model has one field with primary_key=True" 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 ( yield (
"# * Remove `managed = False` lines if you wish to allow " "# * Remove `managed = False` lines if you wish to allow "
"Django to create, modify, and delete the table" "Django to create, modify, and delete the table"
@ -128,6 +129,9 @@ class Command(BaseCommand):
'' if '.' in field_type else 'models.', '' if '.' in field_type else 'models.',
field_type, field_type,
) )
if field_type.startswith('ForeignKey('):
field_desc += ', models.DO_NOTHING'
if extra_params: if extra_params:
if not field_desc.endswith('('): if not field_desc.endswith('('):
field_desc += ', ' field_desc += ', '

View File

@ -18,7 +18,7 @@ from django.db import (
) )
from django.db.models import signals from django.db.models import signals
from django.db.models.constants import LOOKUP_SEP 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 import AutoField
from django.db.models.fields.related import ( from django.db.models.fields.related import (
ForeignObjectRel, ManyToOneRel, OneToOneField, lazy_related_operation, ForeignObjectRel, ManyToOneRel, OneToOneField, lazy_related_operation,
@ -230,8 +230,13 @@ class ModelBase(type):
field = parent_links[base_key] field = parent_links[base_key]
elif not is_proxy: elif not is_proxy:
attr_name = '%s_ptr' % base._meta.model_name attr_name = '%s_ptr' % base._meta.model_name
field = OneToOneField(base, name=attr_name, field = OneToOneField(
auto_created=True, parent_link=True) base,
on_delete=CASCADE,
name=attr_name,
auto_created=True,
parent_link=True,
)
# Only add the ptr field if it's not already present; # Only add the ptr field if it's not already present;
# e.g. migrations will already have it specified # e.g. migrations will already have it specified
if not hasattr(new_class, attr_name): 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.encoding import force_text, smart_text
from django.utils.functional import cached_property, curry from django.utils.functional import cached_property, curry
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import ugettext_lazy as _
from django.utils.version import get_docs_version
RECURSIVE_RELATIONSHIP_CONSTANT = 'self' RECURSIVE_RELATIONSHIP_CONSTANT = 'self'
@ -1584,9 +1585,10 @@ class ForeignObject(RelatedField):
related_accessor_class = ForeignRelatedObjectsDescriptor related_accessor_class = ForeignRelatedObjectsDescriptor
rel_class = ForeignObjectRel 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, related_query_name=None, limit_choices_to=None, parent_link=False,
on_delete=CASCADE, swappable=True, **kwargs): swappable=True, **kwargs):
if rel is None: if rel is None:
rel = self.rel_class( rel = self.rel_class(
self, to, self, to,
@ -1650,14 +1652,14 @@ class ForeignObject(RelatedField):
def deconstruct(self): def deconstruct(self):
name, path, args, kwargs = super(ForeignObject, self).deconstruct() name, path, args, kwargs = super(ForeignObject, self).deconstruct()
kwargs['on_delete'] = self.remote_field.on_delete
kwargs['from_fields'] = self.from_fields kwargs['from_fields'] = self.from_fields
kwargs['to_fields'] = self.to_fields kwargs['to_fields'] = self.to_fields
if self.remote_field.related_name is not None: if self.remote_field.related_name is not None:
kwargs['related_name'] = self.remote_field.related_name kwargs['related_name'] = self.remote_field.related_name
if self.remote_field.related_query_name is not None: if self.remote_field.related_query_name is not None:
kwargs['related_query_name'] = self.remote_field.related_query_name 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: if self.remote_field.parent_link:
kwargs['parent_link'] = self.remote_field.parent_link kwargs['parent_link'] = self.remote_field.parent_link
# Work out string form of "to" # Work out string form of "to"
@ -1866,8 +1868,8 @@ class ForeignKey(ForeignObject):
} }
description = _("Foreign Key (type determined by related field)") description = _("Foreign Key (type determined by related field)")
def __init__(self, to, to_field=None, related_name=None, related_query_name=None, def __init__(self, to, on_delete=None, related_name=None, related_query_name=None,
limit_choices_to=None, parent_link=False, on_delete=CASCADE, limit_choices_to=None, parent_link=False, to_field=None,
db_constraint=True, **kwargs): db_constraint=True, **kwargs):
try: try:
to._meta.model_name to._meta.model_name
@ -1885,6 +1887,28 @@ class ForeignKey(ForeignObject):
# be correct until contribute_to_class is called. Refs #12190. # be correct until contribute_to_class is called. Refs #12190.
to_field = to_field or (to._meta.pk and to._meta.pk.name) 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( kwargs['rel'] = self.rel_class(
self, to, to_field, self, to, to_field,
related_name=related_name, related_name=related_name,
@ -1897,7 +1921,7 @@ class ForeignKey(ForeignObject):
kwargs['db_index'] = kwargs.get('db_index', True) kwargs['db_index'] = kwargs.get('db_index', True)
super(ForeignKey, self).__init__( 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 self.db_constraint = db_constraint
@ -2101,9 +2125,33 @@ class OneToOneField(ForeignKey):
description = _("One-to-one relationship") 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 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): def deconstruct(self):
name, path, args, kwargs = super(OneToOneField, self).deconstruct() 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, related_name='%s+' % name,
db_tablespace=field.db_tablespace, db_tablespace=field.db_tablespace,
db_constraint=field.remote_field.db_constraint, db_constraint=field.remote_field.db_constraint,
on_delete=CASCADE,
), ),
to: models.ForeignKey( to: models.ForeignKey(
to_model, to_model,
related_name='%s+' % name, related_name='%s+' % name,
db_tablespace=field.db_tablespace, db_tablespace=field.db_tablespace,
db_constraint=field.remote_field.db_constraint, 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. * ``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. * ``django.db.models.fields.add_lazy_relation()`` will be removed.
* When time zone support is enabled, database backends that don't support time * 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() pub_date = models.DateField()
headline = models.CharField(max_length=200) headline = models.CharField(max_length=200)
content = models.TextField() content = models.TextField()
reporter = models.ForeignKey(Reporter) reporter = models.ForeignKey(Reporter, on_delete=models.CASCADE)
def __str__(self): # __unicode__ on Python 2 def __str__(self): # __unicode__ on Python 2
return self.headline return self.headline
@ -154,7 +154,7 @@ as easy as registering your model in the admin site:
pub_date = models.DateField() pub_date = models.DateField()
headline = models.CharField(max_length=200) headline = models.CharField(max_length=200)
content = models.TextField() content = models.TextField()
reporter = models.ForeignKey(Reporter) reporter = models.ForeignKey(Reporter, on_delete=models.CASCADE)
.. snippet:: .. snippet::
:filename: mysite/news/admin.py :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): class Choice(models.Model):
question = models.ForeignKey(Question) question = models.ForeignKey(Question, on_delete=models.CASCADE)
choice_text = models.CharField(max_length=200) choice_text = models.CharField(max_length=200)
votes = models.IntegerField(default=0) 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.") slug = models.SlugField(help_text="A short label, generally used in URLs.")
author = models.ForeignKey(User) author = models.ForeignKey(
blog = models.ForeignKey(Blog) User,
models.SET_NULL,
blank=True, null=True,
)
blog = models.ForeignKey(Blog, models.CASCADE)
... ...
def publish(self): def publish(self):

View File

@ -1957,7 +1957,7 @@ information.
name = models.CharField(max_length=100) name = models.CharField(max_length=100)
class Book(models.Model): class Book(models.Model):
author = models.ForeignKey(Author) author = models.ForeignKey(Author, on_delete=models.CASCADE)
title = models.CharField(max_length=100) title = models.CharField(max_length=100)
You can edit the books authored by an author on the author page. You add 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 from django.db import models
class Friendship(models.Model): class Friendship(models.Model):
to_person = models.ForeignKey(Person, related_name="friends") to_person = models.ForeignKey(Person, on_delete=models.CASCADE, related_name="friends")
from_person = models.ForeignKey(Person, related_name="from_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 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 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') members = models.ManyToManyField(Person, through='Membership')
class Membership(models.Model): class Membership(models.Model):
person = models.ForeignKey(Person) person = models.ForeignKey(Person, on_delete=models.CASCADE)
group = models.ForeignKey(Group) group = models.ForeignKey(Group, on_delete=models.CASCADE)
date_joined = models.DateField() date_joined = models.DateField()
invite_reason = models.CharField(max_length=64) invite_reason = models.CharField(max_length=64)
@ -2326,7 +2326,7 @@ you have the following models::
class Image(models.Model): class Image(models.Model):
image = models.ImageField(upload_to="images") image = models.ImageField(upload_to="images")
content_type = models.ForeignKey(ContentType) content_type = models.ForeignKey(ContentType, on_delete=models.CASCADE)
object_id = models.PositiveIntegerField() object_id = models.PositiveIntegerField()
content_object = GenericForeignKey("content_type", "object_id") 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): class TaggedItem(models.Model):
tag = models.SlugField() tag = models.SlugField()
content_type = models.ForeignKey(ContentType) content_type = models.ForeignKey(ContentType, on_delete=models.CASCADE)
object_id = models.PositiveIntegerField() object_id = models.PositiveIntegerField()
content_object = GenericForeignKey('content_type', 'object_id') content_object = GenericForeignKey('content_type', 'object_id')

View File

@ -269,7 +269,7 @@ model::
street = models.CharField(max_length=100) street = models.CharField(max_length=100)
city = models.CharField(max_length=100) city = models.CharField(max_length=100)
state = models.CharField(max_length=2) state = models.CharField(max_length=2)
zipcode = models.ForeignKey(Zipcode) zipcode = models.ForeignKey(Zipcode, on_delete=models.CASCADE)
objects = models.GeoManager() objects = models.GeoManager()
The geographic manager is needed to do spatial queries on related ``Zipcode`` objects, 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): class Article(models.Model):
headline = models.CharField(max_length=200) 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. 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') photo = models.FileField(upload_to='/home/photos')
photographer_name = models.CharField(max_length=100) photographer_name = models.CharField(max_length=100)
pub_date = models.DateField() pub_date = models.DateField()
site = models.ForeignKey(Site) site = models.ForeignKey(Site, on_delete=models.CASCADE)
objects = models.Manager() objects = models.Manager()
on_site = CurrentSiteManager() on_site = CurrentSiteManager()
@ -371,7 +371,7 @@ demonstrates this::
photo = models.FileField(upload_to='/home/photos') photo = models.FileField(upload_to='/home/photos')
photographer_name = models.CharField(max_length=100) photographer_name = models.CharField(max_length=100)
pub_date = models.DateField() pub_date = models.DateField()
publish_on = models.ForeignKey(Site) publish_on = models.ForeignKey(Site, on_delete=models.CASCADE)
objects = models.Manager() objects = models.Manager()
on_site = CurrentSiteManager('publish_on') on_site = CurrentSiteManager('publish_on')

View File

@ -113,7 +113,7 @@ Usage example::
class Comment(models.Model): class Comment(models.Model):
body = models.TextField() body = models.TextField()
modified = models.DateTimeField(auto_now=True) 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 >>> from django.db.models.functions import Greatest
>>> blog = Blog.objects.create(body='Greatest is the best.') >>> 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`` ``ForeignKey``
-------------- --------------
.. class:: ForeignKey(othermodel, **options) .. class:: ForeignKey(othermodel, on_delete, **options)
A many-to-one relationship. Requires a positional argument: the class to which A many-to-one relationship. Requires a positional argument: the class to which
the model is related. 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: .. _recursive-relationships:
To create a recursive relationship -- an object that has a many-to-one 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: .. _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 from django.db import models
class Car(models.Model): class Car(models.Model):
manufacturer = models.ForeignKey('Manufacturer') manufacturer = models.ForeignKey(
'Manufacturer',
on_delete=models.CASCADE,
)
# ... # ...
class Manufacturer(models.Model): class Manufacturer(models.Model):
@ -1147,7 +1157,10 @@ model above is defined in another application called ``production``, you'd
need to use:: need to use::
class Car(models.Model): 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 This sort of reference can be useful when resolving circular import
dependencies between two applications. dependencies between two applications.
@ -1173,8 +1186,79 @@ deal with the field names of your model object.
Arguments Arguments
~~~~~~~~~ ~~~~~~~~~
:class:`ForeignKey` accepts an extra set of arguments -- all optional -- that :class:`ForeignKey` accepts other arguments that define the details of how the
define the details of how the relation works. 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 .. attribute:: ForeignKey.limit_choices_to
@ -1186,7 +1270,11 @@ define the details of how the relation works.
For example:: 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`` causes the corresponding field on the ``ModelForm`` to list only ``Users``
that have ``is_staff=True``. This may be helpful in the Django admin. 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 ensure that the ``User`` model won't have a backwards relation to this
model:: model::
user = models.ForeignKey(User, related_name='+') user = models.ForeignKey(
User,
on_delete=models.CASCADE,
related_name='+',
)
.. attribute:: ForeignKey.related_query_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 # Declare the ForeignKey with related_query_name
class Tag(models.Model): 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) name = models.CharField(max_length=255)
# That's now the name of the reverse filter # 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 If this is set to ``False``, accessing a related object that doesn't exist
will raise its ``DoesNotExist`` exception. 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 .. attribute:: ForeignKey.swappable
Controls the migration framework's reaction if this :class:`ForeignKey` 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 allow_unsaved_instance_assignment = True
class Book(models.Model): class Book(models.Model):
author = UnsavedForeignKey(Author) author = UnsavedForeignKey(Author, on_delete=models.CASCADE)
.. _ref-manytomany: .. _ref-manytomany:
@ -1492,12 +1530,20 @@ that control how the relationship functions.
class Group(models.Model): class Group(models.Model):
name = models.CharField(max_length=128) 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): class Membership(models.Model):
group = models.ForeignKey(Group) group = models.ForeignKey(Group, on_delete=models.CASCADE)
person = models.ForeignKey(Person) person = models.ForeignKey(Person, on_delete=models.CASCADE)
inviter = models.ForeignKey(Person, related_name="membership_invites") inviter = models.ForeignKey(
Person,
on_delete=models.CASCADE,
related_name="membership_invites",
)
invite_reason = models.CharField(max_length=64) invite_reason = models.CharField(max_length=64)
``Membership`` has *two* foreign keys to ``Person`` (``person`` and ``Membership`` has *two* foreign keys to ``Person`` (``person`` and
@ -1577,12 +1623,18 @@ relationship at the database level.
``OneToOneField`` ``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 A one-to-one relationship. Conceptually, this is similar to a
:class:`ForeignKey` with :attr:`unique=True <Field.unique>`, but the :class:`ForeignKey` with :attr:`unique=True <Field.unique>`, but the
"reverse" side of the relation will directly return a single object. "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" This is most useful as the primary key of a model which "extends"
another model in some way; :ref:`multi-table-inheritance` is another model in some way; :ref:`multi-table-inheritance` is
implemented by adding an implicit one-to-one relation from the child 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 from django.db import models
class MySpecialUser(models.Model): class MySpecialUser(models.Model):
user = models.OneToOneField(settings.AUTH_USER_MODEL) user = models.OneToOneField(
supervisor = models.OneToOneField(settings.AUTH_USER_MODEL, related_name='supervisor_of') 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:: 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 .. attribute:: Field.related_model
Points to the model the field relates to. For example, ``Author`` in Points to the model the field relates to. For example, ``Author`` in
``ForeignKey(Author)``. If a field has a generic relation (such as a ``ForeignKey(Author, on_delete=models.CASCADE)``. If a field has a generic
``GenericForeignKey`` or a ``GenericRelation``) then ``related_model`` relation (such as a ``GenericForeignKey`` or a ``GenericRelation``) then
will be ``None``. ``related_model`` will be ``None``.

View File

@ -186,7 +186,7 @@ Django quotes column and table names behind the scenes.
# ... # ...
class Answer(models.Model): class Answer(models.Model):
question = models.ForeignKey(Question) question = models.ForeignKey(Question, on_delete=models.CASCADE)
# ... # ...
class Meta: class Meta:

View File

@ -350,7 +350,11 @@ related model ordering can change the expected results.
Consider this case:: Consider this case::
class Event(Model): class Event(Model):
parent = models.ForeignKey('self', related_name='children') parent = models.ForeignKey(
'self',
on_delete=models.CASCADE,
related_name='children',
)
date = models.DateField() date = models.DateField()
Event.objects.order_by('children__date') Event.objects.order_by('children__date')
@ -806,11 +810,16 @@ following models::
class Person(models.Model): 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): 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)`` ... then a call to ``Book.objects.select_related('author__hometown').get(id=4)``
will cache the related ``Person`` *and* the related ``City``:: will cache the related ``Person`` *and* the related ``City``::

View File

@ -19,7 +19,7 @@ Related objects reference
pass pass
class Article(models.Model): 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 In the above example, the methods below will be available on
the manager ``reporter.article_set``. 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 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. 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 ``Field.rel`` changes
~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~

View File

@ -312,7 +312,7 @@ you might create an Employee model::
from django.contrib.auth.models import User from django.contrib.auth.models import User
class Employee(models.Model): class Employee(models.Model):
user = models.OneToOneField(User) user = models.OneToOneField(User, on_delete=models.CASCADE)
department = models.CharField(max_length=100) department = models.CharField(max_length=100)
Assuming an existing Employee Fred Smith who has both a User and Employee 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 from django.db import models
class Article(models.Model): 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 When connecting to signals sent by the ``User`` model, you should specify
the custom model using the :setting:`AUTH_USER_MODEL` setting. For example:: 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): class Book(models.Model):
title = models.CharField(max_length=100) title = models.CharField(max_length=100)
authors = models.ManyToManyField('Author') authors = models.ManyToManyField('Author')
publisher = models.ForeignKey(Publisher) publisher = models.ForeignKey(Publisher, on_delete=models.CASCADE)
publication_date = models.DateField() publication_date = models.DateField()
Now we need to define a view:: Now we need to define a view::

View File

@ -204,7 +204,7 @@ the foreign key relation to the model:
class Author(models.Model): class Author(models.Model):
name = models.CharField(max_length=200) 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): class Article(models.Model):
headline = models.CharField(max_length=100) headline = models.CharField(max_length=100)
pub_date = models.DateField() pub_date = models.DateField()
reporter = models.ForeignKey(Reporter) reporter = models.ForeignKey(Reporter, on_delete=models.CASCADE)
def __str__(self): # __unicode__ on Python 2 def __str__(self): # __unicode__ on Python 2
return self.headline 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 return "%s the place" % self.name
class Restaurant(models.Model): 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_hot_dogs = models.BooleanField(default=False)
serves_pizza = 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 return "%s the restaurant" % self.place.name
class Waiter(models.Model): class Waiter(models.Model):
restaurant = models.ForeignKey(Restaurant) restaurant = models.ForeignKey(Restaurant, on_delete=models.CASCADE)
name = models.CharField(max_length=50) name = models.CharField(max_length=50)
def __str__(self): # __unicode__ on Python 2 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() objects = PollManager()
class Response(models.Model): class Response(models.Model):
poll = models.ForeignKey(OpinionPoll) poll = models.ForeignKey(OpinionPoll, on_delete=models.CASCADE)
person_name = models.CharField(max_length=50) person_name = models.CharField(max_length=50)
response = models.TextField() response = models.TextField()

View File

@ -99,7 +99,7 @@ Example::
instrument = models.CharField(max_length=100) instrument = models.CharField(max_length=100)
class Album(models.Model): class Album(models.Model):
artist = models.ForeignKey(Musician) artist = models.ForeignKey(Musician, on_delete=models.CASCADE)
name = models.CharField(max_length=100) name = models.CharField(max_length=100)
release_date = models.DateField() release_date = models.DateField()
num_stars = models.IntegerField() 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 :class:`~django.db.models.OneToOneField` require the first argument to be a
model class, so use the :attr:`~Field.verbose_name` keyword argument:: 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") 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 The convention is not to capitalize the first letter of the
:attr:`~Field.verbose_name`. Django will automatically capitalize the first :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 pass
class Car(models.Model): 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 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:: whatever you want. For example::
class Car(models.Model): class Car(models.Model):
company_that_makes_it = models.ForeignKey(Manufacturer) company_that_makes_it = models.ForeignKey(
Manufacturer,
on_delete=models.CASCADE,
)
# ... # ...
.. seealso:: .. seealso::
@ -445,8 +456,8 @@ something like this::
return self.name return self.name
class Membership(models.Model): class Membership(models.Model):
person = models.ForeignKey(Person) person = models.ForeignKey(Person, on_delete=models.CASCADE)
group = models.ForeignKey(Group) group = models.ForeignKey(Group, on_delete=models.CASCADE)
date_joined = models.DateField() date_joined = models.DateField()
invite_reason = models.CharField(max_length=64) 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): 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 Field name restrictions
----------------------- -----------------------

View File

@ -1160,8 +1160,8 @@ Example::
You can override the ``FOO_set`` name by setting the You can override the ``FOO_set`` name by setting the
:attr:`~django.db.models.ForeignKey.related_name` parameter in the :attr:`~django.db.models.ForeignKey.related_name` parameter in the
:class:`~django.db.models.ForeignKey` definition. For example, if the ``Entry`` :class:`~django.db.models.ForeignKey` definition. For example, if the ``Entry``
model was altered to ``blog = ForeignKey(Blog, related_name='entries')``, the model was altered to ``blog = ForeignKey(Blog, on_delete=models.CASCADE,
above example code would look like this:: related_name='entries')``, the above example code would look like this::
>>> b = Blog.objects.get(id=1) >>> b = Blog.objects.get(id=1)
>>> b.entries.all() # Returns all Entry objects related to Blog. >>> b.entries.all() # Returns all Entry objects related to Blog.
@ -1284,7 +1284,7 @@ model.
For example:: For example::
class EntryDetail(models.Model): class EntryDetail(models.Model):
entry = models.OneToOneField(Entry) entry = models.OneToOneField(Entry, on_delete=models.CASCADE)
details = models.TextField() details = models.TextField()
ed = EntryDetail.objects.get(id=2) ed = EntryDetail.objects.get(id=2)

View File

@ -1119,7 +1119,7 @@ you have these two models::
name = models.CharField(max_length=100) name = models.CharField(max_length=100)
class Book(models.Model): class Book(models.Model):
author = models.ForeignKey(Author) author = models.ForeignKey(Author, on_delete=models.CASCADE)
title = models.CharField(max_length=100) title = models.CharField(max_length=100)
If you want to create a formset that allows you to edit books belonging to 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:: the following model::
class Friendship(models.Model): class Friendship(models.Model):
from_friend = models.ForeignKey(Friend, related_name='from_friends') from_friend = models.ForeignKey(
to_friend = models.ForeignKey(Friend, related_name='friends') 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() length_in_months = models.IntegerField()
To resolve this, you can use ``fk_name`` to 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:: their :attr:`~django.db.models.Options.verbose_name` options::
class MyThing(models.Model): class MyThing(models.Model):
kind = models.ForeignKey(ThingKind, related_name='kinds', kind = models.ForeignKey(
verbose_name=_('kind')) 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 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 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 _ from django.utils.translation import ugettext_lazy as _
class MyThing(models.Model): class MyThing(models.Model):
kind = models.ForeignKey(ThingKind, related_name='kinds', kind = models.ForeignKey(
verbose_name=_('kind')) ThingKind,
on_delete=models.CASCADE,
related_name='kinds',
verbose_name=_('kind'),
)
def is_mouse(self): def is_mouse(self):
return self.kind.type == MOUSE_TYPE return self.kind.type == MOUSE_TYPE

View File

@ -344,7 +344,7 @@ Consider the following two models::
class Book(models.Model): class Book(models.Model):
name = models.CharField(max_length=100) 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 Ordinarily, serialized data for ``Book`` would use an integer to refer to
the author. For example, in JSON, a Book might be serialized as:: the author. For example, in JSON, a Book might be serialized as::
@ -514,7 +514,7 @@ example above::
class Book(models.Model): class Book(models.Model):
name = models.CharField(max_length=100) name = models.CharField(max_length=100)
author = models.ForeignKey(Person) author = models.ForeignKey(Person, on_delete=models.CASCADE)
def natural_key(self): def natural_key(self):
return (self.name,) + self.author.natural_key() return (self.name,) + self.author.natural_key()

View File

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

View File

@ -15,7 +15,7 @@ class Album(models.Model):
@python_2_unicode_compatible @python_2_unicode_compatible
class Song(models.Model): class Song(models.Model):
title = models.CharField(max_length=150) title = models.CharField(max_length=150)
album = models.ForeignKey(Album) album = models.ForeignKey(Album, models.CASCADE)
original_release = models.DateField(editable=False) original_release = models.DateField(editable=False)
class Meta: class Meta:
@ -30,8 +30,8 @@ class Song(models.Model):
class TwoAlbumFKAndAnE(models.Model): class TwoAlbumFKAndAnE(models.Model):
album1 = models.ForeignKey(Album, related_name="album1_set") album1 = models.ForeignKey(Album, models.CASCADE, related_name="album1_set")
album2 = models.ForeignKey(Album, related_name="album2_set") album2 = models.ForeignKey(Album, models.CASCADE, related_name="album2_set")
e = models.CharField(max_length=1) e = models.CharField(max_length=1)
@ -47,8 +47,8 @@ class Book(models.Model):
class AuthorsBooks(models.Model): class AuthorsBooks(models.Model):
author = models.ForeignKey(Author) author = models.ForeignKey(Author, models.CASCADE)
book = models.ForeignKey(Book) book = models.ForeignKey(Book, models.CASCADE)
featured = models.BooleanField() featured = models.BooleanField()
@ -57,12 +57,12 @@ class State(models.Model):
class City(models.Model): class City(models.Model):
state = models.ForeignKey(State) state = models.ForeignKey(State, models.CASCADE)
class Influence(models.Model): class Influence(models.Model):
name = models.TextField() name = models.TextField()
content_type = models.ForeignKey(ContentType) content_type = models.ForeignKey(ContentType, models.CASCADE)
object_id = models.PositiveIntegerField() object_id = models.PositiveIntegerField()
content_object = GenericForeignKey('content_type', 'object_id') 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") 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") last_name = models.CharField(max_length=200, help_text="The person's last name")
company = models.ForeignKey(Company, help_text="place of work") company = models.ForeignKey(Company, models.CASCADE, help_text="place of work")
family = models.ForeignKey(Family, related_name='+', null=True) family = models.ForeignKey(Family, models.SET_NULL, related_name='+', null=True)
groups = models.ManyToManyField(Group, help_text="has membership") groups = models.ManyToManyField(Group, help_text="has membership")
def _get_full_name(self): def _get_full_name(self):

View File

@ -13,7 +13,13 @@ from django.utils.encoding import python_2_unicode_compatible
class Book(models.Model): class Book(models.Model):
title = models.CharField(max_length=50) title = models.CharField(max_length=50)
year = models.PositiveIntegerField(null=True, blank=True) 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) contributors = models.ManyToManyField(User, verbose_name="Verbose Contributors", related_name='books_contributed', blank=True)
is_best_seller = models.NullBooleanField(default=0) is_best_seller = models.NullBooleanField(default=0)
date_registered = models.DateField(null=True) date_registered = models.DateField(null=True)
@ -34,7 +40,7 @@ class Department(models.Model):
@python_2_unicode_compatible @python_2_unicode_compatible
class Employee(models.Model): 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) name = models.CharField(max_length=100)
def __str__(self): def __str__(self):
@ -44,7 +50,7 @@ class Employee(models.Model):
@python_2_unicode_compatible @python_2_unicode_compatible
class TaggedItem(models.Model): class TaggedItem(models.Model):
tag = models.SlugField() 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() object_id = models.PositiveIntegerField()
content_object = GenericForeignKey('content_type', 'object_id') content_object = GenericForeignKey('content_type', 'object_id')

View File

@ -31,9 +31,9 @@ class Teacher(models.Model):
@python_2_unicode_compatible @python_2_unicode_compatible
class Child(models.Model): class Child(models.Model):
name = models.CharField(max_length=50) 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() object_id = models.PositiveIntegerField()
parent = GenericForeignKey() parent = GenericForeignKey()
@ -52,7 +52,7 @@ class Author(models.Model):
class NonAutoPKBook(models.Model): class NonAutoPKBook(models.Model):
rand_pk = models.IntegerField(primary_key=True, editable=False) 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) title = models.CharField(max_length=50)
def save(self, *args, **kwargs): def save(self, *args, **kwargs):
@ -65,7 +65,7 @@ class NonAutoPKBook(models.Model):
class EditablePKBook(models.Model): class EditablePKBook(models.Model):
manual_pk = models.IntegerField(primary_key=True) manual_pk = models.IntegerField(primary_key=True)
author = models.ForeignKey(Author) author = models.ForeignKey(Author, models.CASCADE)
title = models.CharField(max_length=50) title = models.CharField(max_length=50)
@ -75,7 +75,7 @@ class Holder(models.Model):
class Inner(models.Model): class Inner(models.Model):
dummy = models.IntegerField() dummy = models.IntegerField()
holder = models.ForeignKey(Holder) holder = models.ForeignKey(Holder, models.CASCADE)
readonly = models.CharField("Inner readonly label", max_length=1) readonly = models.CharField("Inner readonly label", max_length=1)
def get_absolute_url(self): def get_absolute_url(self):
@ -88,7 +88,7 @@ class Holder2(models.Model):
class Inner2(models.Model): class Inner2(models.Model):
dummy = models.IntegerField() dummy = models.IntegerField()
holder = models.ForeignKey(Holder2) holder = models.ForeignKey(Holder2, models.CASCADE)
class Holder3(models.Model): class Holder3(models.Model):
@ -97,7 +97,7 @@ class Holder3(models.Model):
class Inner3(models.Model): class Inner3(models.Model):
dummy = models.IntegerField() dummy = models.IntegerField()
holder = models.ForeignKey(Holder3) holder = models.ForeignKey(Holder3, models.CASCADE)
# Models for ticket #8190 # Models for ticket #8190
@ -108,12 +108,12 @@ class Holder4(models.Model):
class Inner4Stacked(models.Model): class Inner4Stacked(models.Model):
dummy = models.IntegerField(help_text="Awesome stacked help text is awesome.") 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): class Inner4Tabular(models.Model):
dummy = models.IntegerField(help_text="Awesome tabular help text is awesome.") dummy = models.IntegerField(help_text="Awesome tabular help text is awesome.")
holder = models.ForeignKey(Holder4) holder = models.ForeignKey(Holder4, models.CASCADE)
# Models for #12749 # Models for #12749
@ -127,13 +127,13 @@ class OutfitItem(models.Model):
class Fashionista(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) weaknesses = models.ManyToManyField(OutfitItem, through='ShoppingWeakness', blank=True)
class ShoppingWeakness(models.Model): class ShoppingWeakness(models.Model):
fashionista = models.ForeignKey(Fashionista) fashionista = models.ForeignKey(Fashionista, models.CASCADE)
item = models.ForeignKey(OutfitItem) item = models.ForeignKey(OutfitItem, models.CASCADE)
# Models for #13510 # Models for #13510
@ -143,7 +143,7 @@ class TitleCollection(models.Model):
class Title(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) title1 = models.CharField(max_length=100)
title2 = models.CharField(max_length=100) title2 = models.CharField(max_length=100)
@ -155,7 +155,7 @@ class Poll(models.Model):
class Question(models.Model): class Question(models.Model):
poll = models.ForeignKey(Poll) poll = models.ForeignKey(Poll, models.CASCADE)
class Novel(models.Model): class Novel(models.Model):
@ -164,14 +164,14 @@ class Novel(models.Model):
class Chapter(models.Model): class Chapter(models.Model):
name = models.CharField(max_length=40) name = models.CharField(max_length=40)
novel = models.ForeignKey(Novel) novel = models.ForeignKey(Novel, models.CASCADE)
class FootNote(models.Model): class FootNote(models.Model):
""" """
Model added for ticket 19838 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) note = models.CharField(max_length=40)
# Models for #16838 # Models for #16838
@ -183,17 +183,17 @@ class CapoFamiglia(models.Model):
class Consigliere(models.Model): class Consigliere(models.Model):
name = models.CharField(max_length=100, help_text='Help text for Consigliere') 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): class SottoCapo(models.Model):
name = models.CharField(max_length=100) 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): class ReadOnlyInline(models.Model):
name = models.CharField(max_length=100, help_text='Help text for ReadOnlyInline') 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 # Models for #18433
@ -206,7 +206,7 @@ class ParentModelWithCustomPk(models.Model):
class ChildModel1(models.Model): class ChildModel1(models.Model):
my_own_pk = models.CharField(max_length=100, primary_key=True) my_own_pk = models.CharField(max_length=100, primary_key=True)
name = models.CharField(max_length=100) name = models.CharField(max_length=100)
parent = models.ForeignKey(ParentModelWithCustomPk) parent = models.ForeignKey(ParentModelWithCustomPk, models.CASCADE)
def get_absolute_url(self): def get_absolute_url(self):
return '/child_model1/' return '/child_model1/'
@ -215,7 +215,7 @@ class ChildModel1(models.Model):
class ChildModel2(models.Model): class ChildModel2(models.Model):
my_own_pk = models.CharField(max_length=100, primary_key=True) my_own_pk = models.CharField(max_length=100, primary_key=True)
name = models.CharField(max_length=100) name = models.CharField(max_length=100)
parent = models.ForeignKey(ParentModelWithCustomPk) parent = models.ForeignKey(ParentModelWithCustomPk, models.CASCADE)
def get_absolute_url(self): def get_absolute_url(self):
return '/child_model2/' return '/child_model2/'
@ -224,7 +224,7 @@ class ChildModel2(models.Model):
# Models for #19425 # Models for #19425
class BinaryTree(models.Model): class BinaryTree(models.Model):
name = models.CharField(max_length=100) 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 # Models for #19524
@ -238,7 +238,7 @@ class ExtraTerrestrial(LifeForm):
class Sighting(models.Model): class Sighting(models.Model):
et = models.ForeignKey(ExtraTerrestrial) et = models.ForeignKey(ExtraTerrestrial, models.CASCADE)
place = models.CharField(max_length=100) place = models.CharField(max_length=100)
@ -250,7 +250,7 @@ class SomeParentModel(models.Model):
class SomeChildModel(models.Model): class SomeChildModel(models.Model):
name = models.CharField(max_length=1) name = models.CharField(max_length=1)
position = models.PositiveIntegerField() position = models.PositiveIntegerField()
parent = models.ForeignKey(SomeParentModel) parent = models.ForeignKey(SomeParentModel, models.CASCADE)
# Other models # Other models
@ -260,6 +260,6 @@ class ProfileCollection(models.Model):
class Profile(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) first_name = models.CharField(max_length=100)
last_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): class Song(models.Model):
band = models.ForeignKey(Band) band = models.ForeignKey(Band, models.CASCADE)
name = models.CharField(max_length=100) name = models.CharField(max_length=100)
duration = models.IntegerField() duration = models.IntegerField()
other_interpreters = models.ManyToManyField(Band, related_name='covers') 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 # Regression for #13368. This is an example of a model
# that imports a class that has an abstract base class. # that imports a class that has an abstract base class.
class UserProfile(models.Model): 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 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) title = models.CharField(max_length=100)
title2 = models.CharField(max_length=100, verbose_name="another name") title2 = models.CharField(max_length=100, verbose_name="another name")
created = models.DateTimeField() created = models.DateTimeField()
@ -31,7 +31,7 @@ class Article(models.Model):
@python_2_unicode_compatible @python_2_unicode_compatible
class Count(models.Model): class Count(models.Model):
num = models.PositiveSmallIntegerField() num = models.PositiveSmallIntegerField()
parent = models.ForeignKey('self', null=True) parent = models.ForeignKey('self', models.CASCADE, null=True)
def __str__(self): def __str__(self):
return six.text_type(self.num) return six.text_type(self.num)
@ -42,11 +42,11 @@ class Event(models.Model):
class Location(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): class Guest(models.Model):
event = models.OneToOneField(Event) event = models.OneToOneField(Event, models.CASCADE)
name = models.CharField(max_length=255) name = models.CharField(max_length=255)
class Meta: class Meta:
@ -54,7 +54,7 @@ class Guest(models.Model):
class EventGuide(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): class Vehicle(models.Model):
@ -62,7 +62,12 @@ class Vehicle(models.Model):
class VehicleMixin(Vehicle): 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: class Meta:
abstract = True abstract = True

View File

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

View File

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

View File

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

View File

@ -28,7 +28,7 @@ class Publisher(models.Model):
class ItemTag(models.Model): class ItemTag(models.Model):
tag = models.CharField(max_length=100) tag = models.CharField(max_length=100)
content_type = models.ForeignKey(ContentType) content_type = models.ForeignKey(ContentType, models.CASCADE)
object_id = models.PositiveIntegerField() object_id = models.PositiveIntegerField()
content_object = GenericForeignKey('content_type', 'object_id') content_object = GenericForeignKey('content_type', 'object_id')
@ -41,8 +41,8 @@ class Book(models.Model):
rating = models.FloatField() rating = models.FloatField()
price = models.DecimalField(decimal_places=2, max_digits=6) price = models.DecimalField(decimal_places=2, max_digits=6)
authors = models.ManyToManyField(Author) authors = models.ManyToManyField(Author)
contact = models.ForeignKey(Author, related_name='book_contact_set') contact = models.ForeignKey(Author, models.CASCADE, related_name='book_contact_set')
publisher = models.ForeignKey(Publisher) publisher = models.ForeignKey(Publisher, models.CASCADE)
pubdate = models.DateField() pubdate = models.DateField()
tags = GenericRelation(ItemTag) tags = GenericRelation(ItemTag)
@ -72,7 +72,7 @@ class Entries(models.Model):
class Clues(models.Model): class Clues(models.Model):
ID = models.AutoField(primary_key=True) 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) Clue = models.CharField(max_length=150)
@ -102,10 +102,10 @@ class Bravo(models.Model):
class Charlie(models.Model): class Charlie(models.Model):
alfa = models.ForeignKey(Alfa, null=True) alfa = models.ForeignKey(Alfa, models.SET_NULL, null=True)
bravo = models.ForeignKey(Bravo, null=True) bravo = models.ForeignKey(Bravo, models.SET_NULL, null=True)
class SelfRefFK(models.Model): class SelfRefFK(models.Model):
name = models.CharField(max_length=50) 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() rating = models.FloatField()
price = models.DecimalField(decimal_places=2, max_digits=6) price = models.DecimalField(decimal_places=2, max_digits=6)
authors = models.ManyToManyField(Author) authors = models.ManyToManyField(Author)
contact = models.ForeignKey(Author, related_name='book_contact_set') contact = models.ForeignKey(Author, models.CASCADE, related_name='book_contact_set')
publisher = models.ForeignKey(Publisher) publisher = models.ForeignKey(Publisher, models.CASCADE)
pubdate = models.DateField() pubdate = models.DateField()
def __str__(self): def __str__(self):
@ -65,7 +65,7 @@ class Employee(models.Model):
first_name = models.CharField(max_length=20) first_name = models.CharField(max_length=20)
manager = models.BooleanField(default=False) manager = models.BooleanField(default=False)
last_name = models.CharField(max_length=20) last_name = models.CharField(max_length=20)
store = models.ForeignKey(Store) store = models.ForeignKey(Store, models.CASCADE)
age = models.IntegerField() age = models.IntegerField()
salary = models.DecimalField(max_digits=8, decimal_places=2) salary = models.DecimalField(max_digits=8, decimal_places=2)

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -40,7 +40,13 @@ class Article(models.Model):
Article_ID = models.AutoField(primary_key=True, db_column='Article ID') Article_ID = models.AutoField(primary_key=True, db_column='Article ID')
headline = models.CharField(max_length=100) headline = models.CharField(max_length=100)
authors = models.ManyToManyField(Author, db_table='my_m2m_table') 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): def __str__(self):
return self.headline return self.headline

View File

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

View File

@ -48,4 +48,4 @@ class Bar(models.Model):
class Foo(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 @python_2_unicode_compatible
class Comment(models.Model): class Comment(models.Model):
article = models.ForeignKey(Article, related_name="comments") article = models.ForeignKey(Article, models.CASCADE, related_name="comments")
text = models.TextField() text = models.TextField()
pub_date = models.DateField() pub_date = models.DateField()
approval_date = models.DateField(null=True) approval_date = models.DateField(null=True)

View File

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

View File

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

View File

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

View File

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

View File

@ -17,15 +17,15 @@ def get_default_r():
class S(models.Model): class S(models.Model):
r = models.ForeignKey(R) r = models.ForeignKey(R, models.CASCADE)
class T(models.Model): class T(models.Model):
s = models.ForeignKey(S) s = models.ForeignKey(S, models.CASCADE)
class U(models.Model): class U(models.Model):
t = models.ForeignKey(T) t = models.ForeignKey(T, models.CASCADE)
class RChild(R): class RChild(R):
@ -35,33 +35,33 @@ class RChild(R):
class A(models.Model): class A(models.Model):
name = models.CharField(max_length=30) name = models.CharField(max_length=30)
auto = models.ForeignKey(R, related_name="auto_set") auto = models.ForeignKey(R, models.CASCADE, related_name="auto_set")
auto_nullable = models.ForeignKey(R, null=True, auto_nullable = models.ForeignKey(R, models.CASCADE, null=True,
related_name='auto_nullable_set') 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') 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') 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') 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') 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') 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') related_name='cascade_nullable_set')
protect = models.ForeignKey(R, on_delete=models.PROTECT, null=True) protect = models.ForeignKey(R, models.PROTECT, null=True)
donothing = models.ForeignKey(R, on_delete=models.DO_NOTHING, null=True, donothing = models.ForeignKey(R, models.DO_NOTHING, null=True,
related_name='donothing_set') related_name='donothing_set')
child = models.ForeignKey(RChild, related_name="child") child = models.ForeignKey(RChild, models.CASCADE, related_name="child")
child_setnull = models.ForeignKey(RChild, on_delete=models.SET_NULL, null=True, child_setnull = models.ForeignKey(RChild, models.SET_NULL, null=True,
related_name="child_setnull") related_name="child_setnull")
# A OneToOneField is just a ForeignKey unique=True, so we don't duplicate # 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 # all the tests; just one smoke test to ensure on_delete works for it as
# well. # well.
o2o_setnull = models.ForeignKey(R, null=True, o2o_setnull = models.ForeignKey(R, models.SET_NULL, null=True,
on_delete=models.SET_NULL, related_name="o2o_nullable_set") related_name="o2o_nullable_set")
def create_a(name): def create_a(name):
@ -86,13 +86,13 @@ class M(models.Model):
class MR(models.Model): class MR(models.Model):
m = models.ForeignKey(M) m = models.ForeignKey(M, models.CASCADE)
r = models.ForeignKey(R) r = models.ForeignKey(R, models.CASCADE)
class MRNull(models.Model): class MRNull(models.Model):
m = models.ForeignKey(M) m = models.ForeignKey(M, models.CASCADE)
r = models.ForeignKey(R, null=True, on_delete=models.SET_NULL) r = models.ForeignKey(R, models.SET_NULL, null=True)
class Avatar(models.Model): class Avatar(models.Model):
@ -100,15 +100,15 @@ class Avatar(models.Model):
class User(models.Model): class User(models.Model):
avatar = models.ForeignKey(Avatar, null=True) avatar = models.ForeignKey(Avatar, models.CASCADE, null=True)
class HiddenUser(models.Model): class HiddenUser(models.Model):
r = models.ForeignKey(R, related_name="+") r = models.ForeignKey(R, models.CASCADE, related_name="+")
class HiddenUserProfile(models.Model): class HiddenUserProfile(models.Model):
user = models.ForeignKey(HiddenUser) user = models.ForeignKey(HiddenUser, models.CASCADE)
class M2MTo(models.Model): class M2MTo(models.Model):
@ -132,4 +132,4 @@ class Base(models.Model):
class RelToBase(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): class Award(models.Model):
name = models.CharField(max_length=25) name = models.CharField(max_length=25)
object_id = models.PositiveIntegerField() object_id = models.PositiveIntegerField()
content_type = models.ForeignKey(ContentType) content_type = models.ForeignKey(ContentType, models.CASCADE)
content_object = GenericForeignKey() content_object = GenericForeignKey()
class AwardNote(models.Model): class AwardNote(models.Model):
award = models.ForeignKey(Award) award = models.ForeignKey(Award, models.CASCADE)
note = models.CharField(max_length=100) note = models.CharField(max_length=100)
@ -36,13 +36,13 @@ class Child(models.Model):
class PlayedWith(models.Model): class PlayedWith(models.Model):
child = models.ForeignKey(Child) child = models.ForeignKey(Child, models.CASCADE)
toy = models.ForeignKey(Toy) toy = models.ForeignKey(Toy, models.CASCADE)
date = models.DateField(db_column='date_col') date = models.DateField(db_column='date_col')
class PlayedWithNote(models.Model): class PlayedWithNote(models.Model):
played = models.ForeignKey(PlayedWith) played = models.ForeignKey(PlayedWith, models.CASCADE)
note = models.TextField() note = models.TextField()
@ -63,7 +63,7 @@ class Food(models.Model):
class Eaten(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) meal = models.CharField(max_length=20)
@ -75,16 +75,16 @@ class Policy(models.Model):
class Version(models.Model): class Version(models.Model):
policy = models.ForeignKey(Policy) policy = models.ForeignKey(Policy, models.CASCADE)
class Location(models.Model): 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): class Item(models.Model):
version = models.ForeignKey(Version) version = models.ForeignKey(Version, models.CASCADE)
location = models.ForeignKey(Location, blank=True, null=True) location = models.ForeignKey(Location, models.SET_NULL, blank=True, null=True)
# Models for #16128 # Models for #16128
@ -104,15 +104,15 @@ class Photo(Image):
class FooImage(models.Model): class FooImage(models.Model):
my_image = models.ForeignKey(Image) my_image = models.ForeignKey(Image, models.CASCADE)
class FooFile(models.Model): class FooFile(models.Model):
my_file = models.ForeignKey(File) my_file = models.ForeignKey(File, models.CASCADE)
class FooPhoto(models.Model): class FooPhoto(models.Model):
my_photo = models.ForeignKey(Photo) my_photo = models.ForeignKey(Photo, models.CASCADE)
class FooFileProxy(FooFile): class FooFileProxy(FooFile):
@ -126,7 +126,7 @@ class OrgUnit(models.Model):
class Login(models.Model): class Login(models.Model):
description = models.CharField(max_length=32) description = models.CharField(max_length=32)
orgunit = models.ForeignKey(OrgUnit) orgunit = models.ForeignKey(OrgUnit, models.CASCADE)
class House(models.Model): class House(models.Model):
@ -135,7 +135,7 @@ class House(models.Model):
class OrderedPerson(models.Model): class OrderedPerson(models.Model):
name = models.CharField(max_length=32) name = models.CharField(max_length=32)
lives_in = models.ForeignKey(House) lives_in = models.ForeignKey(House, models.CASCADE)
class Meta: class Meta:
ordering = ['name'] ordering = ['name']

View File

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

View File

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

View File

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

View File

@ -10,7 +10,7 @@ from django.utils.encoding import python_2_unicode_compatible
@python_2_unicode_compatible @python_2_unicode_compatible
class RevisionableModel(models.Model): 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) title = models.CharField(blank=True, max_length=255)
when = models.DateTimeField(default=datetime.datetime.now) when = models.DateTimeField(default=datetime.datetime.now)
@ -32,7 +32,7 @@ class RevisionableModel(models.Model):
class Order(models.Model): class Order(models.Model):
created_by = models.ForeignKey(User) created_by = models.ForeignKey(User, models.CASCADE)
text = models.TextField() text = models.TextField()

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -17,7 +17,7 @@ class Media(models.Model):
""" """
Media that can associated to any object. Media that can associated to any object.
""" """
content_type = models.ForeignKey(ContentType) content_type = models.ForeignKey(ContentType, models.CASCADE)
object_id = models.PositiveIntegerField() object_id = models.PositiveIntegerField()
content_object = GenericForeignKey() content_object = GenericForeignKey()
url = models.URLField() url = models.URLField()
@ -36,11 +36,11 @@ class Category(models.Model):
class PhoneNumber(models.Model): class PhoneNumber(models.Model):
content_type = models.ForeignKey(ContentType) content_type = models.ForeignKey(ContentType, models.CASCADE)
object_id = models.PositiveIntegerField() object_id = models.PositiveIntegerField()
content_object = GenericForeignKey('content_type', 'object_id') content_object = GenericForeignKey('content_type', 'object_id')
phone_number = models.CharField(max_length=30) 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: class Meta:
unique_together = (('content_type', 'object_id', 'phone_number',),) 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): class TaggedItem(models.Model):
"""A tag on an item.""" """A tag on an item."""
tag = models.SlugField() tag = models.SlugField()
content_type = models.ForeignKey(ContentType) content_type = models.ForeignKey(ContentType, models.CASCADE)
object_id = models.PositiveIntegerField() object_id = models.PositiveIntegerField()
content_object = GenericForeignKey() content_object = GenericForeignKey()
@ -42,7 +42,7 @@ class ValuableTaggedItem(TaggedItem):
class AbstractComparison(models.Model): class AbstractComparison(models.Model):
comparative = models.CharField(max_length=50) 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() object_id1 = models.PositiveIntegerField()
first_obj = GenericForeignKey(ct_field="content_type1", fk_field="object_id1") 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 A model that tests having multiple GenericForeignKeys. One is defined
through an inherited abstract model and one defined directly on this class. 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() object_id2 = models.PositiveIntegerField()
other_obj = GenericForeignKey(ct_field="content_type2", fk_field="object_id2") other_obj = GenericForeignKey(ct_field="content_type2", fk_field="object_id2")
@ -120,14 +120,14 @@ class ManualPK(models.Model):
class ForProxyModelModel(models.Model): class ForProxyModelModel(models.Model):
content_type = models.ForeignKey(ContentType) content_type = models.ForeignKey(ContentType, models.CASCADE)
object_id = models.PositiveIntegerField() object_id = models.PositiveIntegerField()
obj = GenericForeignKey(for_concrete_model=False) obj = GenericForeignKey(for_concrete_model=False)
title = models.CharField(max_length=255, null=True) title = models.CharField(max_length=255, null=True)
class ForConcreteModelModel(models.Model): class ForConcreteModelModel(models.Model):
content_type = models.ForeignKey(ContentType) content_type = models.ForeignKey(ContentType, models.CASCADE)
object_id = models.PositiveIntegerField() object_id = models.PositiveIntegerField()
obj = GenericForeignKey() obj = GenericForeignKey()
@ -143,6 +143,6 @@ class ProxyRelatedModel(ConcreteRelatedModel):
# To test fix for #7551 # To test fix for #7551
class AllowsNullGFK(models.Model): 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) object_id = models.PositiveIntegerField(null=True)
content_object = GenericForeignKey() content_object = GenericForeignKey()

View File

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

View File

@ -25,7 +25,7 @@ class ManualPrimaryKeyTest(models.Model):
class Profile(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): class Tag(models.Model):
@ -48,4 +48,9 @@ class Author(models.Model):
class Book(models.Model): class Book(models.Model):
name = models.CharField(max_length=100) name = models.CharField(max_length=100)
authors = models.ManyToManyField(Author, related_name='books') 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): class MultiFields(NamedModel):
city = models.ForeignKey(City) city = models.ForeignKey(City, models.CASCADE)
point = models.PointField() point = models.PointField()
poly = models.PolygonField() poly = models.PolygonField()

View File

@ -19,7 +19,12 @@ ops = [
name='Household', name='Household',
fields=[ fields=[
('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)), ('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)), ('address', models.CharField(max_length=100)),
('zip_code', models.IntegerField(null=True, blank=True)), ('zip_code', models.IntegerField(null=True, blank=True)),
('geom', gis_models.PointField(srid=4326, geography=True)), ('geom', gis_models.PointField(srid=4326, geography=True)),
@ -42,7 +47,7 @@ ops = [
migrations.AddField( migrations.AddField(
model_name='household', model_name='household',
name='family', 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, preserve_default=True,
) )
] ]

View File

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

View File

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

View File

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

View File

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

View File

@ -6,20 +6,20 @@ from django.db import models
class People(models.Model): class People(models.Model):
name = models.CharField(max_length=255) name = models.CharField(max_length=255)
parent = models.ForeignKey('self') parent = models.ForeignKey('self', models.CASCADE)
class Message(models.Model): 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): 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) ssn = models.CharField(max_length=11)
class PeopleMoreData(models.Model): 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) license = models.CharField(max_length=255)

View File

@ -144,15 +144,25 @@ class InspectDBTestCase(TestCase):
output = out.getvalue() output = out.getvalue()
error_message = "inspectdb generated an attribute name which is a python keyword" error_message = "inspectdb generated an attribute name which is a python keyword"
# Recursive foreign keys should be set to 'self' # Recursive foreign keys should be set to 'self'
self.assertIn("parent = models.ForeignKey('self')", output) self.assertIn("parent = models.ForeignKey('self', models.DO_NOTHING)", output)
self.assertNotIn("from = models.ForeignKey(InspectdbPeople)", output, msg=error_message) self.assertNotIn(
"from = models.ForeignKey(InspectdbPeople, models.DO_NOTHING)",
output,
msg=error_message,
)
# As InspectdbPeople model is defined after InspectdbMessage, it should be quoted # As InspectdbPeople model is defined after InspectdbMessage, it should be quoted
self.assertIn("from_field = models.ForeignKey('InspectdbPeople', db_column='from_id')", self.assertIn(
output) "from_field = models.ForeignKey('InspectdbPeople', models.DO_NOTHING, db_column='from_id')",
self.assertIn("people_pk = models.ForeignKey(InspectdbPeople, primary_key=True)", output,
output) )
self.assertIn("people_unique = models.ForeignKey(InspectdbPeople, unique=True)", self.assertIn(
output) "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): def test_digits_column_name_introspection(self):
"""Introspection of column names consist/start with digits (#16536/#17676)""" """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) headline = models.CharField(max_length=100)
pub_date = models.DateField() pub_date = models.DateField()
body = models.TextField(default='') body = models.TextField(default='')
reporter = models.ForeignKey(Reporter) reporter = models.ForeignKey(Reporter, models.CASCADE)
response_to = models.ForeignKey('self', null=True) response_to = models.ForeignKey('self', models.SET_NULL, null=True)
def __str__(self): def __str__(self):
return self.headline return self.headline

View File

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

View File

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

View File

@ -17,10 +17,10 @@ class Organiser(models.Model):
class Pool(models.Model): class Pool(models.Model):
name = models.CharField(max_length=30) name = models.CharField(max_length=30)
tournament = models.ForeignKey(Tournament) tournament = models.ForeignKey(Tournament, models.CASCADE)
organiser = models.ForeignKey(Organiser) organiser = models.ForeignKey(Organiser, models.CASCADE)
class PoolStyle(models.Model): class PoolStyle(models.Model):
name = models.CharField(max_length=30) 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): class Article(models.Model):
headline = models.CharField(max_length=100) headline = models.CharField(max_length=100)
pub_date = models.DateTimeField() 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: class Meta:
ordering = ('-pub_date', 'headline') ordering = ('-pub_date', 'headline')
@ -58,7 +58,7 @@ class Season(models.Model):
@python_2_unicode_compatible @python_2_unicode_compatible
class Game(models.Model): 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) home = models.CharField(max_length=100)
away = 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): class Issue(models.Model):
num = models.IntegerField() num = models.IntegerField()
cc = models.ManyToManyField(User, blank=True, related_name='test_issue_cc') 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): def __str__(self):
return six.text_type(self.num) return six.text_type(self.num)

View File

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

View File

@ -32,8 +32,8 @@ class Group(models.Model):
@python_2_unicode_compatible @python_2_unicode_compatible
class Membership(models.Model): class Membership(models.Model):
person = models.ForeignKey(Person) person = models.ForeignKey(Person, models.CASCADE)
group = models.ForeignKey(Group) group = models.ForeignKey(Group, models.CASCADE)
date_joined = models.DateTimeField(default=datetime.now) date_joined = models.DateTimeField(default=datetime.now)
invite_reason = models.CharField(max_length=64, null=True) invite_reason = models.CharField(max_length=64, null=True)
@ -46,9 +46,14 @@ class Membership(models.Model):
@python_2_unicode_compatible @python_2_unicode_compatible
class CustomMembership(models.Model): class CustomMembership(models.Model):
person = models.ForeignKey(Person, db_column="custom_person_column", related_name="custom_person_related_name") person = models.ForeignKey(
group = models.ForeignKey(Group) Person,
weird_fk = models.ForeignKey(Membership, null=True) 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) date_joined = models.DateTimeField(default=datetime.now)
def __str__(self): def __str__(self):
@ -59,8 +64,8 @@ class CustomMembership(models.Model):
class TestNoDefaultsOrNulls(models.Model): class TestNoDefaultsOrNulls(models.Model):
person = models.ForeignKey(Person) person = models.ForeignKey(Person, models.CASCADE)
group = models.ForeignKey(Group) group = models.ForeignKey(Group, models.CASCADE)
nodefaultnonull = models.CharField(max_length=5) nodefaultnonull = models.CharField(max_length=5)
@ -74,8 +79,8 @@ class PersonSelfRefM2M(models.Model):
class Friendship(models.Model): class Friendship(models.Model):
first = models.ForeignKey(PersonSelfRefM2M, related_name="rel_from_set") first = models.ForeignKey(PersonSelfRefM2M, models.CASCADE, related_name="rel_from_set")
second = models.ForeignKey(PersonSelfRefM2M, related_name="rel_to_set") second = models.ForeignKey(PersonSelfRefM2M, models.CASCADE, related_name="rel_to_set")
date_friended = models.DateTimeField() date_friended = models.DateTimeField()
@ -90,10 +95,10 @@ class Event(models.Model):
class Invitation(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". # field order is deliberately inverted. the target field is "invitee".
inviter = models.ForeignKey(Person, related_name='invitations_sent') inviter = models.ForeignKey(Person, models.CASCADE, related_name='invitations_sent')
invitee = models.ForeignKey(Person, related_name='invitations') invitee = models.ForeignKey(Person, models.CASCADE, related_name='invitations')
@python_2_unicode_compatible @python_2_unicode_compatible
@ -110,9 +115,9 @@ class Employee(models.Model):
class Relationship(models.Model): class Relationship(models.Model):
# field order is deliberately inverted. # field order is deliberately inverted.
another = models.ForeignKey(Employee, related_name="rel_another_set", null=True) another = models.ForeignKey(Employee, models.SET_NULL, related_name="rel_another_set", null=True)
target = models.ForeignKey(Employee, related_name="rel_target_set") target = models.ForeignKey(Employee, models.CASCADE, related_name="rel_target_set")
source = models.ForeignKey(Employee, related_name="rel_source_set") source = models.ForeignKey(Employee, models.CASCADE, related_name="rel_source_set")
class Ingredient(models.Model): class Ingredient(models.Model):
@ -133,5 +138,5 @@ class Recipe(models.Model):
class RecipeIngredient(models.Model): class RecipeIngredient(models.Model):
ingredient = models.ForeignKey(Ingredient, to_field='iname') ingredient = models.ForeignKey(Ingredient, models.CASCADE, to_field='iname')
recipe = models.ForeignKey(Recipe, to_field='rname') 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 # Forward declared intermediate model
@python_2_unicode_compatible @python_2_unicode_compatible
class Membership(models.Model): class Membership(models.Model):
person = models.ForeignKey('Person') person = models.ForeignKey('Person', models.CASCADE)
group = models.ForeignKey('Group') group = models.ForeignKey('Group', models.CASCADE)
price = models.IntegerField(default=100) price = models.IntegerField(default=100)
def __str__(self): def __str__(self):
@ -20,8 +20,8 @@ class Membership(models.Model):
@python_2_unicode_compatible @python_2_unicode_compatible
class UserMembership(models.Model): class UserMembership(models.Model):
id = models.AutoField(db_column='usermembership_id', primary_key=True) id = models.AutoField(db_column='usermembership_id', primary_key=True)
user = models.ForeignKey(User) user = models.ForeignKey(User, models.CASCADE)
group = models.ForeignKey('Group') group = models.ForeignKey('Group', models.CASCADE)
price = models.IntegerField(default=100) price = models.IntegerField(default=100)
def __str__(self): def __str__(self):
@ -53,8 +53,8 @@ class A(models.Model):
class ThroughBase(models.Model): class ThroughBase(models.Model):
a = models.ForeignKey(A) a = models.ForeignKey(A, models.CASCADE)
b = models.ForeignKey('B') b = models.ForeignKey('B', models.CASCADE)
class Through(ThroughBase): class Through(ThroughBase):
@ -89,8 +89,8 @@ class Driver(models.Model):
@python_2_unicode_compatible @python_2_unicode_compatible
class CarDriver(models.Model): class CarDriver(models.Model):
car = models.ForeignKey('Car', to_field='make') car = models.ForeignKey('Car', models.CASCADE, to_field='make')
driver = models.ForeignKey('Driver', to_field='name') driver = models.ForeignKey('Driver', models.CASCADE, to_field='name')
def __str__(self): def __str__(self):
return "pk=%s car=%s driver=%s" % (str(self.pk), self.car, self.driver) 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 Relating an object to itself, many-to-one
To define a many-to-one relationship between a model and itself, use 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 In this example, a ``Category`` is related to itself. That is, each
``Category`` has a parent ``Category``. ``Category`` has a parent ``Category``.
@ -17,7 +17,7 @@ from django.utils.encoding import python_2_unicode_compatible
@python_2_unicode_compatible @python_2_unicode_compatible
class Category(models.Model): class Category(models.Model):
name = models.CharField(max_length=20) 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): def __str__(self):
return self.name return self.name
@ -26,8 +26,8 @@ class Category(models.Model):
@python_2_unicode_compatible @python_2_unicode_compatible
class Person(models.Model): class Person(models.Model):
full_name = models.CharField(max_length=20) full_name = models.CharField(max_length=20)
mother = models.ForeignKey('self', null=True, related_name='mothers_child_set') mother = models.ForeignKey('self', models.SET_NULL, null=True, related_name='mothers_child_set')
father = models.ForeignKey('self', null=True, related_name='fathers_child_set') father = models.ForeignKey('self', models.SET_NULL, null=True, related_name='fathers_child_set')
def __str__(self): def __str__(self):
return self.full_name return self.full_name

View File

@ -137,11 +137,11 @@ class RelatedModel(models.Model):
@python_2_unicode_compatible @python_2_unicode_compatible
class RelationModel(models.Model): 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') 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_id = models.IntegerField(null=True)
gfk = GenericForeignKey(ct_field='gfk_ctype', fk_field='gfk_id') gfk = GenericForeignKey(ct_field='gfk_ctype', fk_field='gfk_id')

View File

@ -23,7 +23,7 @@ class Reporter(models.Model):
class Article(models.Model): class Article(models.Model):
headline = models.CharField(max_length=100) headline = models.CharField(max_length=100)
pub_date = models.DateField() pub_date = models.DateField()
reporter = models.ForeignKey(Reporter) reporter = models.ForeignKey(Reporter, models.CASCADE)
def __str__(self): def __str__(self):
return self.headline return self.headline
@ -40,27 +40,27 @@ class First(models.Model):
class Second(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. # Protect against repetition of #1839, #2415 and #2536.
class Third(models.Model): class Third(models.Model):
name = models.CharField(max_length=20) 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): class Parent(models.Model):
name = models.CharField(max_length=20, unique=True) 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): class Child(models.Model):
name = models.CharField(max_length=20) name = models.CharField(max_length=20)
parent = models.ForeignKey(Parent) parent = models.ForeignKey(Parent, models.CASCADE)
class ToFieldChild(models.Model): 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) # Multiple paths to the same model (#7110, #7125)
@ -73,13 +73,13 @@ class Category(models.Model):
class Record(models.Model): class Record(models.Model):
category = models.ForeignKey(Category) category = models.ForeignKey(Category, models.CASCADE)
@python_2_unicode_compatible @python_2_unicode_compatible
class Relation(models.Model): class Relation(models.Model):
left = models.ForeignKey(Record, related_name='left_set') left = models.ForeignKey(Record, models.CASCADE, related_name='left_set')
right = models.ForeignKey(Record, related_name='right_set') right = models.ForeignKey(Record, models.CASCADE, related_name='right_set')
def __str__(self): def __str__(self):
return "%s - %s" % (self.left.category.name, self.right.category.name) return "%s - %s" % (self.left.category.name, self.right.category.name)
@ -97,4 +97,4 @@ class School(models.Model):
class Student(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) name = models.CharField(max_length=50)
class BandMember(models.Model): class BandMember(models.Model):
band = UnsavedForeignKey(Band) band = UnsavedForeignKey(Band, models.CASCADE)
first_name = models.CharField(max_length=50) first_name = models.CharField(max_length=50)
last_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): def test_fk_instantiation_outside_model(self):
# Regression for #12190 -- Should be able to instantiate a FK outside # Regression for #12190 -- Should be able to instantiate a FK outside
# of a model, and interrogate its related field. # 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) self.assertEqual('id', cat.remote_field.get_related_field().name)
def test_relation_unsaved(self): def test_relation_unsaved(self):

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