Re: [Django] #7623: Multi-table inheritance does not allow linking new instance of child model to existing parent model instance.

39 views
Skip to first unread message

Django

unread,
Sep 16, 2011, 5:58:59 PM9/16/11
to django-...@googlegroups.com
#7623: Multi-table inheritance does not allow linking new instance of child model
to existing parent model instance.
-------------------------------------+-------------------------------------
Reporter: | Owner: nobody
brooks.travis@… | Status: closed
Type: Bug | Component: Database layer
Milestone: | (models, ORM)
Version: SVN | Severity: Normal
Resolution: needsinfo | Keywords: model-inheritance,
Triage Stage: Design | multi-table-inheritance
decision needed | Has patch: 1
Needs documentation: 1 | Needs tests: 1
Patch needs improvement: 1 | Easy pickings: 0
UI/UX: 0 |
-------------------------------------+-------------------------------------
Changes (by Alex):

* status: new => closed
* ui_ux: => 0
* resolution: => needsinfo
* easy: => 0


Comment:

Discussion with Jacob: closing as needsinfo, the modeling in the ticket
does not seem like it *should* work, a model cannot be an instance of
multiple subclasses.

--
Ticket URL: <https://code.djangoproject.com/ticket/7623#comment:12>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.

Django

unread,
Nov 22, 2011, 4:28:16 PM11/22/11
to django-...@googlegroups.com
#7623: Multi-table inheritance does not allow linking new instance of child model
to existing parent model instance.
-------------------------------------+-------------------------------------
Reporter: brooks.travis@… | Owner: nobody
Type: Bug | Status: reopened
Component: Database layer | Version: SVN
(models, ORM) | Resolution:
Severity: Normal | Triage Stage: Design
Keywords: model-inheritance, | decision needed
multi-table-inheritance | Needs documentation: 1
Has patch: 1 | Patch needs improvement: 1
Needs tests: 1 | UI/UX: 0
Easy pickings: 0 |
-------------------------------------+-------------------------------------
Changes (by Nan):

* status: closed => reopened
* resolution: needsinfo =>


Comment:

Here's a more reasonable example...

{{{
# models.py
class Place(models.Model):
name = models.CharField(max_length=50)
address = models.CharField(max_length=80)

class Restaurant(Place):
place = models.OneToOneField(Place, parent_link=True,
related_name='restaurant')
serves_hot_dogs = models.BooleanField()
serves_pizza = models.BooleanField()
}}}

Now, say we have a bunch of Place objects in the database, and a form
where users can inform us what sort of business a particular Place is (OK,
this is a contrived example, but I'm sure you can see that this could be a
reasonable use case for some types of data).

{{{
# somewhere in views.py
p = Place.objects.get(pk=1)
restaurant = Restaurant(**{
'place': p,
'serves_hot_dogs': False,
'serves_pizza': True,
})
restaurant.save()
}}}

--
Ticket URL: <https://code.djangoproject.com/ticket/7623#comment:13>

Django

unread,
Dec 12, 2011, 12:06:51 PM12/12/11
to django-...@googlegroups.com
#7623: Multi-table inheritance does not allow linking new instance of child model
to existing parent model instance.
-------------------------------------+-------------------------------------
Reporter: brooks.travis@… | Owner: nobody
Type: Bug | Status: closed
Component: Database layer | Version: SVN
(models, ORM) | Resolution: wontfix
Severity: Normal | Triage Stage: Design
Keywords: model-inheritance, | decision needed
multi-table-inheritance | Needs documentation: 1
Has patch: 1 | Patch needs improvement: 1
Needs tests: 1 | UI/UX: 0
Easy pickings: 0 |
-------------------------------------+-------------------------------------
Changes (by aaugustin):

* status: reopened => closed
* resolution: => wontfix


Comment:

If multiple related objects are linked to the same object, they should
have a foreign key to this object, not "extend" it; that would break the
"instance" paradigm.

You can always use a Python mixin if you have related objects of different
types, but want to share some methods.

--
Ticket URL: <https://code.djangoproject.com/ticket/7623#comment:14>

Django

unread,
Dec 20, 2011, 3:56:43 PM12/20/11
to django-...@googlegroups.com
#7623: Multi-table inheritance does not allow linking new instance of child model
to existing parent model instance.
-------------------------------------+-------------------------------------
Reporter: brooks.travis@… | Owner: nobody
Type: Bug | Status: reopened
Component: Database layer | Version: SVN
(models, ORM) | Resolution:
Severity: Normal | Triage Stage: Design
Keywords: model-inheritance, | decision needed
multi-table-inheritance | Needs documentation: 1
Has patch: 1 | Patch needs improvement: 1
Needs tests: 1 | UI/UX: 0
Easy pickings: 0 |
-------------------------------------+-------------------------------------
Changes (by Nan):

* status: closed => reopened

* resolution: wontfix =>


Comment:

Please see my example immediately above. This is not about foreign keys
or multiple related objects linked to the same object. It's about multi-
table inheritance where the child data isn't always known at the time the
parent object is created.

If you have a Place object that is not yet a Restaurant object, the ORM
will not allow you to add the data to make it a Restaurant object.

--
Ticket URL: <https://code.djangoproject.com/ticket/7623#comment:15>

Django

unread,
Dec 23, 2011, 5:06:45 AM12/23/11
to django-...@googlegroups.com
#7623: Multi-table inheritance does not allow linking new instance of child model
to existing parent model instance.
-------------------------------------+-------------------------------------
Reporter: brooks.travis@… | Owner: nobody
Type: Bug | Status: closed
Component: Database layer | Version: SVN
(models, ORM) | Resolution:
Severity: Normal | worksforme
Keywords: model-inheritance, | Triage Stage: Design
multi-table-inheritance | decision needed
Has patch: 1 | Needs documentation: 1
Needs tests: 1 | Patch needs improvement: 1
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by aaugustin):

* status: reopened => closed

* resolution: => worksforme


Comment:

Ah, I understand. This works:

{{{
p = Place.objects.get(pk=1)
restaurant = Restaurant(place_ptr=p, ...)
}}}

--
Ticket URL: <https://code.djangoproject.com/ticket/7623#comment:16>

Django

unread,
Dec 23, 2011, 5:52:04 AM12/23/11
to django-...@googlegroups.com
#7623: Multi-table inheritance does not allow linking new instance of child model
to existing parent model instance.
-------------------------------------+-------------------------------------
Reporter: brooks.travis@… | Owner: nobody
Type: Bug | Status: reopened
Component: Database layer | Version: SVN
(models, ORM) | Resolution:
Severity: Normal | Triage Stage: Design
Keywords: model-inheritance, | decision needed
multi-table-inheritance | Needs documentation: 1
Has patch: 1 | Patch needs improvement: 1
Needs tests: 1 | UI/UX: 0
Easy pickings: 0 |
-------------------------------------+-------------------------------------
Changes (by bunyan):

* status: closed => reopened

* resolution: worksforme =>


Comment:

This leads to the behavior described in #11618 - the parent instance
fields get overwritten.

--
Ticket URL: <https://code.djangoproject.com/ticket/7623#comment:17>

Django

unread,
Dec 23, 2011, 3:25:02 PM12/23/11
to django-...@googlegroups.com
#7623: Multi-table inheritance does not allow linking new instance of child model
to existing parent model instance.
-------------------------------------+-------------------------------------
Reporter: brooks.travis@… | Owner: nobody
Type: Bug | Status: reopened
Component: Database layer | Version: SVN
(models, ORM) | Resolution:
Severity: Normal | Triage Stage: Design
Keywords: model-inheritance, | decision needed
multi-table-inheritance | Needs documentation: 1
Has patch: 1 | Patch needs improvement: 1
Needs tests: 1 | UI/UX: 0
Easy pickings: 0 |
-------------------------------------+-------------------------------------
Changes (by akaariai):

* cc: anssi.kaariainen@… (added)


Comment:

If you want to extend an existing instance, you need to copy all fields of
the parent to the new child manually. Unfortunately this can't be done in
a generic way using only public APIs. Although ._meta is semi-public and
doing
{{{
child = ChildModel(**childfields) # set child field values
for field in parent._meta.fields:
setattr(child, field.attname, getattr(parent, field.attname)) # set
child values from parent
child.parent_ptr = parent.pk # not sure if this is strictly necessary,
probably so...
}}}
or something along those lines should work (not tested). Now, I don't
think this can be officially documented without making ._meta.fields part
of the public API. I would have use for a helper method that does this.

--
Ticket URL: <https://code.djangoproject.com/ticket/7623#comment:18>

Django

unread,
Jun 7, 2012, 1:43:34 PM6/7/12
to django-...@googlegroups.com
#7623: Multi-table inheritance does not allow linking new instance of child model
to existing parent model instance.
-------------------------------------+-------------------------------------
Reporter: brooks.travis@… | Owner: nobody
Type: Bug | Status: reopened
Component: Database layer | Version: master
(models, ORM) | Resolution:
Severity: Normal | Triage Stage: Design
Keywords: model-inheritance, | decision needed
multi-table-inheritance | Needs documentation: 1
Has patch: 1 | Patch needs improvement: 1
Needs tests: 1 | UI/UX: 0
Easy pickings: 0 |
-------------------------------------+-------------------------------------
Changes (by carbonXT):

* cc: mike@… (added)


--
Ticket URL: <https://code.djangoproject.com/ticket/7623#comment:19>

Django

unread,
Jul 9, 2012, 12:28:51 PM7/9/12
to django-...@googlegroups.com
#7623: Multi-table inheritance does not allow linking new instance of child model
to existing parent model instance.
-------------------------------------+-------------------------------------
Reporter: brooks.travis@… | Owner: nobody
Type: Bug | Status: reopened
Component: Database layer | Version: master
(models, ORM) | Resolution:
Severity: Normal | Triage Stage: Design
Keywords: model-inheritance, | decision needed
multi-table-inheritance | Needs documentation: 1
Has patch: 1 | Patch needs improvement: 1
Needs tests: 1 | UI/UX: 0
Easy pickings: 0 |
-------------------------------------+-------------------------------------

Comment (by Edward Askew <gnutrino@…>):

There's actually an easier workaround for this:


{{{
parent = Place.objects.get(...)
child = Restaurant(place_ptr=parent,...)

#Overwrites the parents fields except the primary key with None (because
the parent fields in child are not auto filled)
child.save()

#Restores the parent fields to their previous values
parent.save()

#hit the database again to fill the proper values for the inherited fields
child = Restaurant.objects.get(pk=parent.pk)
}}}

--
Ticket URL: <https://code.djangoproject.com/ticket/7623#comment:20>

Django

unread,
Oct 2, 2012, 10:12:42 AM10/2/12
to django-...@googlegroups.com
#7623: Multi-table inheritance does not allow linking new instance of child model
to existing parent model instance.
-------------------------------------+-------------------------------------
Reporter: brooks.travis@… | Owner: nobody
Type: Bug | Status: reopened
Component: Database layer | Version: master
(models, ORM) | Resolution:
Severity: Normal | Triage Stage: Design
Keywords: model-inheritance, | decision needed
multi-table-inheritance | Needs documentation: 1
Has patch: 1 | Patch needs improvement: 1
Needs tests: 1 | UI/UX: 0
Easy pickings: 0 |
-------------------------------------+-------------------------------------

Comment (by sammiestoel@…):

There is an even easier work around not 100% sure if it works as expected
yet though:

{{{
child = Restaurant(place_ptr_id=place.pk)
child.__dict__.update(place.__dict__)
child.save()
}}}

Tested it myself for my use case as working.
Thanks to: http://stackoverflow.com/questions/4064808/django-model-
inheritance-create-sub-instance-of-existing-instance-downcast

--
Ticket URL: <https://code.djangoproject.com/ticket/7623#comment:21>

Django

unread,
Feb 26, 2013, 2:01:10 PM2/26/13
to django-...@googlegroups.com
#7623: Multi-table inheritance does not allow linking new instance of child model
to existing parent model instance.
-------------------------------------+-------------------------------------
Reporter: brooks.travis@… | Owner: nobody
Type: Bug | Status: reopened
Component: Database layer | Version: master
(models, ORM) | Resolution:
Severity: Normal | Triage Stage: Design
Keywords: model-inheritance, | decision needed
multi-table-inheritance | Needs documentation: 1
Has patch: 1 | Patch needs improvement: 1
Needs tests: 1 | UI/UX: 0
Easy pickings: 0 |
-------------------------------------+-------------------------------------

Comment (by loic84):

I'm not sure it covers all bases but I use:

{{{
child = Restaurant(place_ptr=place)
child.save_base(raw=True)
}}}

It would be great to have an obvious and officially blessed way of doing
this though.

--
Ticket URL: <https://code.djangoproject.com/ticket/7623#comment:22>

Django

unread,
Mar 22, 2013, 6:30:28 PM3/22/13
to django-...@googlegroups.com
#7623: Multi-table inheritance does not allow linking new instance of child model
to existing parent model instance.
-------------------------------------+-------------------------------------
Reporter: brooks.travis@… | Owner: nobody
Type: Bug | Status: new

Component: Database layer | Version: master
(models, ORM) | Resolution:
Severity: Normal | Triage Stage: Accepted
Keywords: model-inheritance, | Needs documentation: 1
multi-table-inheritance | Patch needs improvement: 1
Has patch: 1 | UI/UX: 0
Needs tests: 1 |
Easy pickings: 0 |
-------------------------------------+-------------------------------------
Changes (by akaariai):

* stage: Design decision needed => Accepted


Comment:

I think this makes sense. Unlink child but keep the parent and link child
to existing parent would both be useful in some situatios.

--
Ticket URL: <https://code.djangoproject.com/ticket/7623#comment:24>

Django

unread,
May 18, 2013, 3:06:08 PM5/18/13
to django-...@googlegroups.com
#7623: Multi-table inheritance does not allow linking new instance of child model
to existing parent model instance.
-------------------------------------+-------------------------------------
Reporter: brooks.travis@… | Owner:
Type: Bug | elektrrrus
Component: Database layer | Status: assigned
(models, ORM) | Version: master
Severity: Normal | Resolution:
Keywords: model-inheritance, | Triage Stage: Accepted

multi-table-inheritance | Needs documentation: 1
Has patch: 1 | Patch needs improvement: 1
Needs tests: 1 | UI/UX: 0
Easy pickings: 0 |
-------------------------------------+-------------------------------------
Changes (by elektrrrus):

* status: new => assigned
* owner: nobody => elektrrrus


--
Ticket URL: <https://code.djangoproject.com/ticket/7623#comment:25>

Django

unread,
Dec 2, 2013, 8:57:34 AM12/2/13
to django-...@googlegroups.com
#7623: Multi-table inheritance does not allow linking new instance of child model
to existing parent model instance.
-------------------------------------+-------------------------------------
Reporter: brooks.travis@… | Owner:
Type: Bug | elektrrrus
Component: Database layer | Status: assigned
(models, ORM) | Version: master
Severity: Normal | Resolution:
Keywords: model-inheritance, | Triage Stage: Accepted
multi-table-inheritance | Needs documentation: 1
Has patch: 1 | Patch needs improvement: 1
Needs tests: 1 | UI/UX: 0
Easy pickings: 0 |
-------------------------------------+-------------------------------------

Comment (by aaugustin):

#21537 was a duplicate.

--
Ticket URL: <https://code.djangoproject.com/ticket/7623#comment:26>

Django

unread,
Dec 19, 2013, 9:47:05 PM12/19/13
to django-...@googlegroups.com
#7623: Multi-table inheritance does not allow linking new instance of child model
to existing parent model instance.
-------------------------------------+-------------------------------------
Reporter: brooks.travis@… | Owner:
Type: Bug | elektrrrus
Component: Database layer | Status: assigned
(models, ORM) | Version: master
Severity: Normal | Resolution:
Keywords: model-inheritance, | Triage Stage: Accepted
multi-table-inheritance | Needs documentation: 1
Has patch: 1 | Patch needs improvement: 1
Needs tests: 1 | UI/UX: 0
Easy pickings: 0 |
-------------------------------------+-------------------------------------

Comment (by pcompassion):

I'd like this to be implemented as well. I have the following model
relationships and it's just hard to do what django expects me to do when
creating objects.

Thread has 1 main post.
Thread has many other posts
Post has 0-1 parent post.

There are multiple type of Threads.

It's just easier to work with when I can create BaseThread and extend it.

Besides, there are cases where I need to switch Thread types.
If it's possible to treat the base and extended separately, I can keep the
base part, and create the extension part, and connect them.

--
Ticket URL: <https://code.djangoproject.com/ticket/7623#comment:27>

Django

unread,
Jan 26, 2014, 4:45:00 AM1/26/14
to django-...@googlegroups.com
#7623: Multi-table inheritance does not allow linking new instance of child model
to existing parent model instance.
-------------------------------------+-------------------------------------
Reporter: brooks.travis@… | Owner:
Type: Bug | elektrrrus
Component: Database layer | Status: assigned
(models, ORM) | Version: master
Severity: Normal | Resolution:
Keywords: model-inheritance, | Triage Stage: Accepted
multi-table-inheritance | Needs documentation: 1
Has patch: 1 | Patch needs improvement: 1
Needs tests: 1 | UI/UX: 0
Easy pickings: 0 |
-------------------------------------+-------------------------------------

Comment (by Reza Mohammadi <reza@…>):

`raw=True` doesn't always work. `raw` is used for two different purposes:

The 'raw' argument is telling save_base not to save any parent models
and
not to do any changes to the values before save. This is used by fixture
loading.

For the purpose of this ticket, we want save_base ignore the first part
but we need the second part to be done.

I think `raw` argument should be split to two different arguments, as its
functionality is already separated. Not as a workaround for this bug, but
to make the code more readable.

--
Ticket URL: <https://code.djangoproject.com/ticket/7623#comment:28>

Django

unread,
Jan 26, 2014, 4:45:30 AM1/26/14
to django-...@googlegroups.com
#7623: Multi-table inheritance does not allow linking new instance of child model
to existing parent model instance.
-------------------------------------+-------------------------------------
Reporter: brooks.travis@… | Owner:
Type: Bug | elektrrrus
Component: Database layer | Status: assigned
(models, ORM) | Version: master
Severity: Normal | Resolution:
Keywords: model-inheritance, | Triage Stage: Accepted
multi-table-inheritance | Needs documentation: 1
Has patch: 1 | Patch needs improvement: 1
Needs tests: 1 | UI/UX: 0
Easy pickings: 0 |
-------------------------------------+-------------------------------------
Changes (by Reza Mohammadi <reza@…>):

* cc: reza@… (added)


--
Ticket URL: <https://code.djangoproject.com/ticket/7623#comment:29>

Django

unread,
Feb 3, 2014, 9:47:52 AM2/3/14
to django-...@googlegroups.com
#7623: Multi-table inheritance does not allow linking new instance of child model
to existing parent model instance.
-------------------------------------+-------------------------------------
Reporter: brooks.travis@… | Owner:
Type: Bug | elektrrrus
Component: Database layer | Status: assigned
(models, ORM) | Version: master
Severity: Normal | Resolution:
Keywords: model-inheritance, | Triage Stage: Accepted
multi-table-inheritance | Needs documentation: 1
Has patch: 1 | Patch needs improvement: 1
Needs tests: 1 | UI/UX: 0
Easy pickings: 0 |
-------------------------------------+-------------------------------------

Comment (by juan64645@…):

Hello! I am new in django. I have a problem like this.
I want to do something like this(in inheritance multi-table):

in view.py

restaurant = Restaurant(place_ptr=place)
restaurant.save()

assuming that the attributes of restaurant hold null=True.
but Restaurant(place_ptr=place) returns nothing.

My vercion of django is 1.5
They say about this? Is there any alternative?
That is not to create a new restaurant and it was clear the place, because
it is very ugly.

From already thank you very much!

--
Ticket URL: <https://code.djangoproject.com/ticket/7623#comment:30>

Django

unread,
Jan 26, 2015, 12:42:30 PM1/26/15
to django-...@googlegroups.com
#7623: Multi-table inheritance: create child instance from existing parent
-------------------------------------+-------------------------------------
Reporter: brooks.travis@… | Owner:
| elektrrrus
Type: Bug | Status: assigned

Component: Database layer | Version: master
(models, ORM) |
Severity: Normal | Resolution:
Keywords: model-inheritance, | Triage Stage: Accepted
multi-table-inheritance |
Has patch: 1 | Needs documentation: 1
Needs tests: 1 | Patch needs improvement: 1

Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by collinanderson):

* cc: cmawebsite@… (added)


--
Ticket URL: <https://code.djangoproject.com/ticket/7623#comment:31>

Django

unread,
Sep 20, 2015, 1:14:50 PM9/20/15
to django-...@googlegroups.com
#7623: Multi-table inheritance: create child instance from existing parent
-------------------------------------+-------------------------------------
Reporter: brooks.travis@… | Owner:
| elektrrrus
Type: Bug | Status: assigned
Component: Database layer | Version: master
(models, ORM) |
Severity: Normal | Resolution:
Keywords: model-inheritance, | Triage Stage: Accepted
multi-table-inheritance |
Has patch: 1 | Needs documentation: 1
Needs tests: 1 | Patch needs improvement: 1
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by ar45):

* cc: ar45 (added)


--
Ticket URL: <https://code.djangoproject.com/ticket/7623#comment:32>

Django

unread,
Sep 21, 2015, 10:02:11 PM9/21/15
to django-...@googlegroups.com
#7623: Multi-table inheritance: create child instance from existing parent
-------------------------------------+-------------------------------------
Reporter: brooks.travis@… | Owner:
| elektrrrus
Type: Bug | Status: assigned
Component: Database layer | Version: master
(models, ORM) |
Severity: Normal | Resolution:
Keywords: model-inheritance, | Triage Stage: Accepted
multi-table-inheritance |
Has patch: 1 | Needs documentation: 1
Needs tests: 1 | Patch needs improvement: 1
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------

Comment (by ar45):

Anything wrong with [1] this implementation? (taken from Tom Tobin's
branch referenced in this ticket)

[1]
https://github.com/django/django/compare/master...ar45:child_object_from_parent_model

--
Ticket URL: <https://code.djangoproject.com/ticket/7623#comment:33>

Django

unread,
Oct 8, 2015, 3:28:41 PM10/8/15
to django-...@googlegroups.com
#7623: Multi-table inheritance: create child instance from existing parent
-------------------------------------+-------------------------------------
Reporter: brooks.travis@… | Owner:
| elektrrrus
Type: Bug | Status: assigned
Component: Database layer | Version: master
(models, ORM) |
Severity: Normal | Resolution:
Keywords: model-inheritance, | Triage Stage: Accepted
multi-table-inheritance |
Has patch: 1 | Needs documentation: 1
Needs tests: 1 | Patch needs improvement: 1
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------

Comment (by timgraham):

It's a bit difficult to review without tests. To get a review of the API
design, it's a good idea to offer a high level overview on the
DevelopersMailingList.

--
Ticket URL: <https://code.djangoproject.com/ticket/7623#comment:34>

Reply all
Reply to author
Forward
0 new messages