From 6d4df45e2927c45344b9f014f739466d61f808c8 Mon Sep 17 00:00:00 2001 From: Tim Graham Date: Mon, 28 Apr 2014 09:28:03 -0400 Subject: [PATCH] [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 --- docs/releases/1.7.txt | 1 + docs/topics/db/models.txt | 63 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 64 insertions(+) diff --git a/docs/releases/1.7.txt b/docs/releases/1.7.txt index c27d5b96fa1..98a6d7cca01 100644 --- a/docs/releases/1.7.txt +++ b/docs/releases/1.7.txt @@ -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 diff --git a/docs/topics/db/models.txt b/docs/topics/db/models.txt index d5a700f62e4..097fdae0e3f 100644 --- a/docs/topics/db/models.txt +++ b/docs/topics/db/models.txt @@ -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 "", line 1, in + 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 -------------------------------------