Commit 8ec388a6 authored by Tim Graham's avatar Tim Graham
Browse files

Fixed #22442 -- Provided additional documentation regarding id fields clashing.

Thanks benjaoming for raising the issue and Loic for the examples.
parent d9c272b2
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -1194,6 +1194,7 @@ Miscellaneous
  fields in the model inheritance hierarchy results in a system check error.
  For example, if you use multi-inheritance, you need to define custom primary
  key fields on parent models, otherwise the default ``id`` fields will clash.
  See :ref:`model-multiple-inheritance-topic` for details.

* ``django.utils.translation.parse_accept_lang_header()`` now returns
  lowercase locales, instead of the case as it was provided. As locales should
+63 −0
Original line number Diff line number Diff line
@@ -1262,6 +1262,8 @@ So, the general rules are:
   This sets things up so that the proxy model is an exact copy of the
   storage structure of the original model when data is saved.

.. _model-multiple-inheritance-topic:

Multiple inheritance
--------------------

@@ -1279,6 +1281,67 @@ inheritance hierarchies as simple and straightforward as possible so that you
won't have to struggle to work out where a particular piece of information is
coming from.

.. versionchanged:: 1.7

Before Django 1.7, inheriting from multiple models that had an ``id`` primary
key field did not raise an error, but could result in data loss. For example,
consider these models (which no longer validate due to the clashing ``id``
fields)::

    class Article(models.Model):
        headline = models.CharField(max_length=50)
        body = models.TextField()

    class Book(models.Model):
        title = models.CharField(max_length=50)

    class BookReview(Book, Article):
        pass

This snippet demonstrates how creating a child object overwrote the value of a
previously created parent object::

    >>> article = Article.objects.create(headline='Some piece of news.')
    >>> review = BookReview.objects.create(
    ...     headline='Review of Little Red Riding Hood.',
    ...     title='Little Red Riding Hood')
    >>>
    >>> assert Article.objects.get(pk=article.pk).headline == article.headline
    Traceback (most recent call last):
      File "<console>", line 1, in <module>
    AssertionError
    >>> # the "Some piece of news." headline has been overwritten.
    >>> Article.objects.get(pk=article.pk).headline
    'Review of Little Red Riding Hood.'

To properly use multiple inheritance, you can use an explicit
:class:`~django.db.models.AutoField` in the base models::

    class Article(models.Model):
        article_id = models.AutoField(primary_key=True)
        ...

    class Book(models.Model):
        book_id = models.AutoField(primary_key=True)
        ...

    class BookReview(Book, Article):
        pass

Or use a common ancestor to hold the :class:`~django.db.models.AutoField`::

    class Piece(models.Model):
        pass

    class Article(Piece):
        ...

    class Book(Piece):
        ...

    class BookReview(Book, Article):
        pass

Field name "hiding" is not permitted
-------------------------------------