Opened 18 years ago

Closed 17 years ago

#2828 closed defect (fixed)

TypeError when deleting objects with ManyToMany(self) relationships in the admin

Reported by: anonymous Owned by: Adrian Holovaty
Component: contrib.admin Version:
Severity: normal Keywords:
Cc: 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

When trying to delete an object with a ManyToMany(self) relationship you get a "TypeError getattr(): attribute name must be string". Have played a little around it and it seems to work correctly when adding "filter_interface=models.HORIZONTAL" to the ManyToManyField(self) Field.

Error:
TypeError at /admin/person/person/2/delete/
getattr(): attribute name must be string

Produces an error:

class Person(models.Model):
    name = models.CharField(maxlength=20)
    friends = models.ManyToManyField('self',blank=True)
    idols = models.ManyToManyField('self', symmetrical=False,related_name='stalkers',blank=True)

    def __str__(self):
        return self.name

    class Admin:
        pass 

Works ok:

class Person(models.Model):
    name = models.CharField(maxlength=20)
    friends = models.ManyToManyField('self',blank=True)
    idols = models.ManyToManyField('self', symmetrical=False,related_name='stalkers',blank=True,filter_interface=models.HORIZONTAL)

    def __str__(self):
        return self.name

    class Admin:
        pass 

Change History (5)

comment:1 by anonymous, 18 years ago

Still doesn't work, also with filter_interface=models.HORIZONTAL.

comment:2 by Gary Wilson <gary.wilson@…>, 17 years ago

It would be helpful to include the full traceback.

comment:3 by james.mulholland@…, 17 years ago

See:

http://groups.google.com/group/django-developers/browse_thread/thread/b8584e0ea9e4d544/a502482e449e28b0#a502482e449e28b0

AFAICT, the solution posted in that thread by Brian Beck does work, although I haven't thoroughly tested it yet. The changes are:

In file django/contrib/admin/views/main.py at line 463, replace:

463:    has_related_objs = False
464:    rel_objs = getattr(obj, rel_opts_name, None)

with

463:    has_related_objs = False
464:    if rel_opts_name:
465:        rel_objs = getattr(obj, rel_opts_name, None)
466:    else:
467:        rel_objs = None

In file django/db/models/related.py comment lines 135 and 136:

134:    # If this is a symmetrical m2m relation on self, there is no reverse accessor.
135:    if getattr(self.field.rel, 'symmetrical', False) and self.model == self.parent_model:
136:        return None

Change to:

134:    # If this is a symmetrical m2m relation on self, there is no reverse accessor.
135:    #if getattr(self.field.rel, 'symmetrical', False) and self.model == self.parent_model:
136:    #    return None

comment:4 by Simon G. <dev@…>, 17 years ago

Has patch: set
Triage Stage: UnreviewedReady for checkin
Version: 0.95

comment:5 by Jacob, 17 years ago

Resolution: fixed
Status: newclosed

(In [4616]) Fixed #2828, a TypeError when deleting objects with m2m relations to self. Thanks, Brian Beck.

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