[1.7.x] Fixed #22442 -- Provided additional documentation regarding id fields clashing.

Thanks benjaoming for raising the issue and Loic for the examples.

Backport of 8ec388a69d from master
This commit is contained in:
Tim Graham 2014-04-28 09:28:03 -04:00
parent a2cac1b68d
commit 6d4df45e29
2 changed files with 64 additions and 0 deletions

View File

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

View File

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