"getattr(): attribute name must be string"

2,702 views
Skip to first unread message

James

unread,
Nov 29, 2006, 10:04:14 AM11/29/06
to Django developers
This bug was submitted a couple of months ago:

http://code.djangoproject.com/ticket/2828

but unfortunately I just got bitten by it :( Is there a fix, or will
one be forthcoming? Or is there a workaround (the one in the ticket
doesn't work, in fact)?

TIA.

--
James

Russell Keith-Magee

unread,
Nov 30, 2006, 12:56:29 AM11/30/06
to django-d...@googlegroups.com

The ticket itself is the best guide to any knowledge about the problem; in this case, I'm guessing that the answer is no - there isn't a patch or workaround. Any help you can provide in tracking the problem (and/or fixing it) would be greatfully accepted.

Yours,
Russ Magee %-)

Brian Beck

unread,
Nov 30, 2006, 2:47:08 AM11/30/06
to Django developers
> The ticket itself is the best guide to any knowledge about the problem; in
> this case, I'm guessing that the answer is no - there isn't a patch or
> workaround. Any help you can provide in tracking the problem (and/or fixing
> it) would be greatfully accepted.

Here's a more complete traceback:

Traceback (most recent call last):
File "/usr/lib/python2.4/site-packages/django/core/handlers/base.py" in
get_response
74. response = callback(request, *callback_args, **callback_kwargs)
File
"/usr/lib/python2.4/site-packages/django/contrib/admin/views/decorators.py"
in _checklogin
55. return view_func(request, *args, **kwargs)
File
"/usr/lib/python2.4/site-packages/django/views/decorators/cache.py" in
_wrapped_view_func
39. response = view_func(request, *args, **kwargs)
File
"/usr/lib/python2.4/site-packages/django/contrib/admin/views/main.py"
in delete_stage
503. _get_deleted_objects(deleted_objects, perms_needed,
request.user, obj, opts, 1)
File
"/usr/lib/python2.4/site-packages/django/contrib/admin/views/main.py"
in _get_deleted_objects
464. rel_objs = getattr(obj, rel_opts_name, None)

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

There seem to be two relevant pieces of code:

In _get_deleted_objects:
rel_opts_name = related.get_accessor_name()
has_related_objs = False
rel_objs = getattr(obj, rel_opts_name, None)
if rel_objs:
has_related_objs = True

related.get_accessor_name() can return None, this doesn't account for
that. So let's see get_accessor_name, which says:

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

I tried both commenting out that special case check in
get_accessor_name and adding a couple lines to _get_deleted_objects:
rel_opts_name = related.get_accessor_name()
has_related_objs = False
if rel_opts_name:
rel_objs = getattr(obj, rel_opts_name, None)
else:
rel_objs = None
if rel_objs:
has_related_objs = True

This case in particular seems to work fine when either or both of these
changes are applied, but I'm not sure if they break something else or
are secretly making the database all messy. Anyway, the key point is
that anything using get_accessor_name() should take None into account,
or None should never be returned.

James

unread,
Nov 30, 2006, 4:28:36 AM11/30/06
to Django developers
> Any help you can provide in tracking the problem (and/or fixing
> it) would be greatfully accepted.

I had a brief look at the code, and (despite my limited Python
knowledge) was going to pitch in if I could. Given Brian's detailed
response, I shall probably apply the fixes he suggests and spend some
time to check if anything else gets broken in consequence, or if the
database is indeed getting messed up. I'll post if I find anything
conclusive either way.

Thanks for the responses :)

--
James

Russell Keith-Magee

unread,
Nov 30, 2006, 5:49:52 AM11/30/06
to django-d...@googlegroups.com
On 11/30/06, Brian Beck <exo...@gmail.com> wrote:
>
> Anyway, the key point is
> that anything using get_accessor_name() should take None into account,
> or None should never be returned.

The former approach would be correct. get_accessor_name() shouldn't
return a value if the m2m relation is symmetrical on self, because
there is no reverse accessor. The existence of the None return value
is used during syncdb model validation.

Yours,
Russ Magee %-)

Russell Keith-Magee

unread,
Nov 30, 2006, 5:52:31 AM11/30/06
to django-d...@googlegroups.com

If you do work out a fix (or if Brian's fix turns out to be exactly
what is needed), don't forget to write a regression test or two to
validate the change.

Yours,
Russ Magee %-)

James

unread,
Nov 30, 2006, 8:45:06 AM11/30/06
to Django developers
Brian, splendid stuff :) Seems to work so far, at least in terms of
keeping database integrity and actually doing what it's supposed to.
Thanks very much for taking the time to post this solution.

Now how do I write a regression test? Any docs available?

--
James

Waylan Limberg

unread,
Nov 30, 2006, 9:23:50 AM11/30/06
to django-d...@googlegroups.com
On 11/30/06, James <james.mu...@gmail.com> wrote:
>
> Brian, splendid stuff :) Seems to work so far, at least in terms of
> keeping database integrity and actually doing what it's supposed to.
> Thanks very much for taking the time to post this solution.

Tests or not, be sure to post the fixes to the ticket (and perhaps a
link to this thread) so is doesn't get lost.


>
> Now how do I write a regression test? Any docs available?
>
> --
> James
>
>
> >
>


--
----
Waylan Limberg
way...@gmail.com

James

unread,
Nov 30, 2006, 11:31:34 AM11/30/06
to Django developers
Waylan Limberg wrote:

> Tests or not, be sure to post the fixes to the ticket (and perhaps a
> link to this thread) so is doesn't get lost.

It is done.

--
James

Russell Keith-Magee

unread,
Nov 30, 2006, 7:13:36 PM11/30/06
to django-d...@googlegroups.com
On 11/30/06, James <james.mu...@gmail.com> wrote:

No docs - they are just standard unittests and doctests. You can execute them using the trunk/tests/runtests.py script, passing in a --settings option. The tests themselves are in tests/modeltests and tests/regressiontests. Model tests are intended to be examples of model/feature use (which double as testing); regressiontests are intended to be tests of specific behaviour that doesn't serve any tutorial purpose.


Yours,
Russ Magee %-)

Phil Powell

unread,
Dec 7, 2006, 6:13:36 AM12/7/06
to django-d...@googlegroups.com
I'm just wondering if anyone is following up on this issue, as I've
just been bitten by it? Or I'd happy to pull together some diff's and
have a shot at some regression tests - but don't want to tread on
anyone's toes?

-Phil

chris....@gmail.com

unread,
Dec 17, 2006, 10:02:44 PM12/17/06
to Django developers
It doesn't look like anything is being done with it right now. I
believe the patch outlined in the code works but I haven't thoroughly
tested it.

I'd like to see it fixed too. If you need help, let me know.

-Chris

Reply all
Reply to author
Forward
0 new messages