Opened 8 years ago

Closed 7 years ago

#26362 closed Bug (fixed)

Manually changing the parent of a child model is silently failing.

Reported by: Keith Hostetler Owned by: Paulo
Component: Database layer (models, ORM) Version: 1.8
Severity: Normal Keywords:
Cc: Triage Stage: Accepted
Has patch: yes Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description

To be honest, I have no idea if it is supposed to be allowed to set the parent via the parent_ptr, but it isn't working. If it isn't allowed, it should be reporting an error.

Example:

class Parent(models.Model):
    field1 = models.TextField(default="abc")

class Child(Parent):
    field2 = models.TextField(default="abc")

def change_parent():
    child = Child.objects.get(id=1)
    new_parent = Parent.objects.create()

    print child.id  # Prints 1
    print child.parent_ptr.id  # Prints 1
    print new_parent.id  # We'll say it is number 5
    child.parent_ptr = new_parent

    print child.id  # Prints 1
    print child.parent_ptr.id  # Prints 5
    child.save()

    print child.id  # Prints 1
    print child.parent_ptr.id  # Prints 1

This applies to the update function as well. I tried:

    Child.objects.filter(id=1).update(parent_ptr=new_parent)
    child = Child.objects.get(id=1)

    print child.id  # Prints 1
    print child.parent_ptr.id  # Prints 1

Change History (5)

comment:1 by Tim Graham, 8 years ago

Triage Stage: UnreviewedAccepted

The first point seems to be a valid issue. In particular, after assigning a new parent, the pk attribute is updated, but not the id. I think this can be fixed but I'm not 100% sure.

>>> child.parent_ptr = new_parent
>>> child.pk
2
>>> child.id
1

As for the second issue, QuerySet.update() is working for me.

>>> child = Child.objects.create()
>>> child_pk = child.id
>>> new_parent = Parent.objects.create()
>>> Child.objects.filter(id=child.pk).update(parent_ptr=new_parent)
>>> Child.objects.get(pk=child_pk)
...
DoesNotExist: Child matching query does not exist.

(make sense since the Child with the old pk no longer exists)

in reply to:  1 comment:2 by Keith Hostetler, 8 years ago

Replying to timgraham:

As for the second issue, QuerySet.update() is working for me.

>>> child = Child.objects.create()
>>> child_pk = child.id
>>> new_parent = Parent.objects.create()
>>> Child.objects.filter(id=child.pk).update(parent_ptr=new_parent)
>>> Child.objects.get(pk=child_pk)
...
DoesNotExist: Child matching query does not exist.

(make sense since the Child with the old pk no longer exists)

Ah, yes. You are right. I didn't technically test that code, but was written based upon what I actually did and I realize now that I simply had a reference issue.

comment:3 by Paulo, 7 years ago

Owner: changed from nobody to Paulo
Status: newassigned

comment:5 by Tim Graham <timograham@…>, 7 years ago

Resolution: fixed
Status: assignedclosed

In c4329271:

Fixed #26362 -- Fixed update of the inherited id field of an object when its parent changes.

Note: See TracTickets for help on using tickets.
Back to Top