Opened 5 years ago

Closed 5 years ago

Last modified 5 years ago

#24940 closed Bug (fixed)

unhashable type: 'RelatedManager' when deleting a model using django admin that has GenericRelation and related_query_name

Reported by: Federico Jaramillo Martínez Owned by: Markus Holtermann
Component: contrib.admin Version: 1.8
Severity: Release blocker Keywords:
Cc: Markus Holtermann Triage Stage: Ready for checkin
Has patch: yes Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description

Ok, a few things before he report:

  • This is my first Django bug report (hope I do well)
  • Didn't know how else to call the report, a better summary is appreciated.

The problem:
When using django admin to delete an instance of a model that has a GenericRelation with a related_query_name, an "unhashable type: 'RelatedManager'" error is thrown.

If the related_query_name is removed, the error disappears.

Example structure:

...

class ModelA(models.Model):

    """Model with GenericForeignKey."""

    content_type = models.ForeignKey(ContentType)
    object_id = models.PositiveIntegerField()
    content_object = GenericForeignKey()


class ModelB(models.Model):

    """Model with a GenericRelation and related_query_name."""

    model_a = GenericRelation(ComponenteContable, related_query_name='model_a')


class ModelC(models.Model):

    """Model with a GenericRelation and related_query_name."""

    model_c = GenericRelation(ComponenteContable, related_query_name='model_c')


class ModelD(models.Model):

    """Model with a GenericRelation and related_query_name."""

    model_d = GenericRelation(ComponenteContable, related_query_name='model_d')

...

It is not possible to delete a model B, C or D instance in django admin if the have a related_query_name.

The moment you remove related_query_name, that Model's instances can be deleted.

Attachments (1)

24940-test.diff (2.2 KB) - added by Tim Graham 5 years ago.

Download all attachments as: .zip

Change History (7)

comment:1 Changed 5 years ago by Federico Jaramillo Martínez

A bit of debugging shows that when deleting an instance, django admin finds all the instances that are related to it in order to delete them as well.

Problem is the dictionary created to store all the related instances to be deleted uses those same instances as keys in order to recursively find the whole tree.

When GenericRelation has a related_query_name, it generates a dynamic "RelatedManager" class that is not hashable.

This all happens in a NestedObjects class defined in django.contrib.admin.utils

From there, I got lost.

comment:2 Changed 5 years ago by Tim Graham

Cc: Markus Holtermann added
Severity: NormalRelease blocker
Triage Stage: UnreviewedAccepted

Bisected to aa5ef0d4fc67a95ac2a5103810d0c87d8c547bac. Attaching a regression test for Django's test suite.

Changed 5 years ago by Tim Graham

Attachment: 24940-test.diff added

comment:3 Changed 5 years ago by Markus Holtermann

Has patch: set
Owner: changed from nobody to Markus Holtermann
Status: newassigned

comment:4 Changed 5 years ago by Tim Graham

Triage Stage: AcceptedReady for checkin

comment:5 Changed 5 years ago by Markus Holtermann <info@…>

Resolution: fixed
Status: assignedclosed

In d3d66d4:

Fixed #24940 -- Made model managers hashable

Thanks Federico Jaramillo Martínez for the report and Tim Graham for the
test and review.

comment:6 Changed 5 years ago by Markus Holtermann <info@…>

In f64a3de2:

[1.8.x] Fixed #24940 -- Made model managers hashable

Thanks Federico Jaramillo Martínez for the report and Tim Graham for the
test and review.

Backport of d3d66d47222dd8765a20a15fdc754c0ed7635404 from master

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