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
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.
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
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 %-)
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 %-)
Now how do I write a regression test? Any docs available?
--
James
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
> 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
-Phil
I'd like to see it fixed too. If you need help, let me know.
-Chris