Commit b55cde05 authored by Alex Gaynor's avatar Alex Gaynor
Browse files

Added a db_constraint option to ForeignKeys.

This controls whether or not a database level cosntraint is created. This is useful in a few specialized circumstances, but in general should not be used!
parent cb5545ea
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -77,7 +77,7 @@ class BaseDatabaseCreation(object):
                    tablespace, inline=True)
                if tablespace_sql:
                    field_output.append(tablespace_sql)
            if f.rel:
            if f.rel and f.db_constraint:
                ref_output, pending = self.sql_for_inline_foreign_key_references(
                    model, f, known_models, style)
                if pending:
+5 −3
Original line number Diff line number Diff line
@@ -981,9 +981,10 @@ class ForeignKey(RelatedField, Field):
    }
    description = _("Foreign Key (type determined by related field)")

    def __init__(self, to, to_field=None, rel_class=ManyToOneRel, **kwargs):
    def __init__(self, to, to_field=None, rel_class=ManyToOneRel,
                 db_constraint=True, **kwargs):
        try:
            to_name = to._meta.model_name
            to._meta.model_name
        except AttributeError:  # to._meta doesn't exist, so it must be RECURSIVE_RELATIONSHIP_CONSTANT
            assert isinstance(to, six.string_types), "%s(%r) is invalid. First parameter to ForeignKey must be either a model, a model name, or the string %r" % (self.__class__.__name__, to, RECURSIVE_RELATIONSHIP_CONSTANT)
        else:
@@ -997,13 +998,14 @@ class ForeignKey(RelatedField, Field):
        if 'db_index' not in kwargs:
            kwargs['db_index'] = True

        self.db_constraint = db_constraint
        kwargs['rel'] = rel_class(to, to_field,
            related_name=kwargs.pop('related_name', None),
            limit_choices_to=kwargs.pop('limit_choices_to', None),
            parent_link=kwargs.pop('parent_link', False),
            on_delete=kwargs.pop('on_delete', CASCADE),
        )
        Field.__init__(self, **kwargs)
        super(ForeignKey, self).__init__(**kwargs)

    def get_path_info(self):
        """
+13 −0
Original line number Diff line number Diff line
@@ -1051,6 +1051,19 @@ define the details of how the relation works.
    The field on the related object that the relation is to. By default, Django
    uses the primary key of the related object.

.. attribute:: ForeignKey.db_constraint

    Controls whether or not a constraint should be created in the database for
    this foreign key. The default is ``True``, and that's almost certainly what
    you want; setting this to ``False`` can be very bad for data integrity.
    That said, here are some scenarios where you might want to do this:

    * You have legacy data that is not valid.
    * You're sharding your database.

    If you use this, accessing a related object that doesn't exist will raise
    its ``DoesNotExist`` exception.

.. attribute:: ForeignKey.on_delete

    When an object referenced by a :class:`ForeignKey` is deleted, Django by
+3 −0
Original line number Diff line number Diff line
@@ -85,6 +85,9 @@ Minor features
  :class:`~django.http.HttpResponsePermanentRedirect` now provide an ``url``
  attribute (equivalent to the URL the response will redirect to).

* Added the :attr:`django.db.models.ForeignKey.db_constraint`
  option.

Backwards incompatible changes in 1.6
=====================================

+14 −1
Original line number Diff line number Diff line
@@ -86,3 +86,16 @@ class Item(models.Model):

    def __str__(self):
        return self.name


@python_2_unicode_compatible
class Object(models.Model):
    pass


@python_2_unicode_compatible
class ObjectReference(models.Model):
    obj = models.ForeignKey(Object, db_constraint=False)

    def __str__(self):
        return str(self.obj_id)
Loading