[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:
parent
a2cac1b68d
commit
6d4df45e29
|
@ -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
|
||||
|
|
|
@ -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
|
||||
-------------------------------------
|
||||
|
||||
|
|
Loading…
Reference in New Issue