[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. 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 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. 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 * ``django.utils.translation.parse_accept_lang_header()`` now returns
lowercase locales, instead of the case as it was provided. As locales should 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 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. storage structure of the original model when data is saved.
.. _model-multiple-inheritance-topic:
Multiple inheritance 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 won't have to struggle to work out where a particular piece of information is
coming from. 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 Field name "hiding" is not permitted
------------------------------------- -------------------------------------