Opened 3 years ago

Closed 3 years ago

Last modified 3 years ago

#19114 closed Bug (fixed)

admin LogEntry __unicode__() returns a proxy in some cases

Reported by: niko@… Owned by: EmilStenstrom
Component: contrib.admin Version: 1.4
Severity: Normal Keywords: proxy unicode logentry admin
Cc: Triage Stage: Ready for checkin
Has patch: yes Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: yes UI/UX: no

Description (last modified by claudep)

the admin LogEntry function __unicode__() returns a proxy object for lazzy translation string in the case the self.action_flag is different from 1 2 or 3.

This leads to an exception in the admin when trying to delete such LogEntry or an associated object of it, when the admin needs its name to be displayed in the "delete confirmation" page.

the fix is to cast to unicode the returned value in line 46 of
django/contrib/admin/models.py

return unicode(_('LogEntry Object'))

it is because we are using a custom action_flag of 4 in some of our LogEntry, that the bug popped up.
You will notice that the 3 other cases in the __unicode__ function are not problematic because they are printf and therefor a new unicode string is geenrated and returned, and the proxy is "gettext-ed" before.

the exception was:

  File "/usr/local/lib/python2.6/dist-packages/django/core/handlers/base.py", line 111, in get_response
    response = callback(request, *callback_args, **callback_kwargs)

  File "/usr/local/lib/python2.6/dist-packages/django/contrib/admin/options.py", line 366, in wrapper
    return self.admin_site.admin_view(view)(*args, **kwargs)

  File "/usr/local/lib/python2.6/dist-packages/django/utils/decorators.py", line 91, in _wrapped_view
    response = view_func(request, *args, **kwargs)

  File "/usr/local/lib/python2.6/dist-packages/django/views/decorators/cache.py", line 89, in _wrapped_view_func
    response = view_func(request, *args, **kwargs)

  File "/usr/local/lib/python2.6/dist-packages/django/contrib/admin/sites.py", line 196, in inner
    return view(request, *args, **kwargs)

  File "/usr/local/lib/python2.6/dist-packages/django/utils/decorators.py", line 25, in _wrapper
    return bound_func(*args, **kwargs)

  File "/usr/local/lib/python2.6/dist-packages/django/utils/decorators.py", line 91, in _wrapped_view
    response = view_func(request, *args, **kwargs)

  File "/usr/local/lib/python2.6/dist-packages/django/utils/decorators.py", line 21, in bound_func
    return func(self, *args2, **kwargs2)

  File "/usr/local/lib/python2.6/dist-packages/django/db/transaction.py", line 209, in inner
    return func(*args, **kwargs)

  File "/usr/local/lib/python2.6/dist-packages/django/contrib/admin/options.py", line 1274, in delete_view
    [obj], opts, request.user, self.admin_site, using)

  File "/usr/local/lib/python2.6/dist-packages/django/contrib/admin/util.py", line 132, in get_deleted_objects
    to_delete = collector.nested(format_callback)

  File "/usr/local/lib/python2.6/dist-packages/django/contrib/admin/util.py", line 186, in nested
    roots.extend(self._nested(root, seen, format_callback))

  File "/usr/local/lib/python2.6/dist-packages/django/contrib/admin/util.py", line 169, in _nested
    children.extend(self._nested(child, seen, format_callback))

  File "/usr/local/lib/python2.6/dist-packages/django/contrib/admin/util.py", line 171, in _nested
    ret = [format_callback(obj)]

  File "/usr/local/lib/python2.6/dist-packages/django/contrib/admin/util.py", line 130, in format_callback
    force_unicode(obj))

  File "/usr/local/lib/python2.6/dist-packages/django/utils/encoding.py", line 71, in force_unicode
    s = unicode(s)

TypeError: coercing to Unicode: need string or buffer, __proxy__ found

Change History (8)

comment:1 Changed 3 years ago by claudep

  • Description modified (diff)
  • Easy pickings set
  • Has patch unset
  • Needs documentation unset
  • Needs tests unset
  • Patch needs improvement unset
  • Triage Stage changed from Unreviewed to Accepted

I think that there is no need to call ugettext_lazy in the __str__ method. ugettext should be fine here.

comment:2 Changed 3 years ago by beda

As this situation occurs in the case when the action_flag attribute does not match any of the predefined constants, I think that we could kill two birds with one stone by adding the action_flag to the unicode output in this case. This makes the unicode representation reflect the action_flag value and also deals with the bug at hand:

46c46
<         return _('LogEntry Object')
---
>         return _('LogEntry Object, action-flag=%(action_flag)d') % {'action_flag': self.action_flag}

comment:3 Changed 3 years ago by EmilStenstrom

  • Owner changed from nobody to EmilStenstrom

comment:4 Changed 3 years ago by EmilStenstrom

We are currently sprinting in Stockholm and are going to fix this bug like this:

Since __str__ will be called at runtime we don't need to use the lazy version of ugettext. This means no artificial string formatting will need to be added. Patch is coming.

comment:5 Changed 3 years ago by EmilStenstrom

  • Has patch set

Here's a patch that fixes the issue. One new test added, all tests pass: https://github.com/django/django/pull/523

comment:6 Changed 3 years ago by jezdez

  • Triage Stage changed from Accepted to Ready for checkin

comment:7 Changed 3 years ago by Claude Paroz <claude@…>

  • Resolution set to fixed
  • Status changed from new to closed

In e0363c688d9b85124ec4fbac00debe5f4dc1e63c:

Fixed #19114 -- Fixed LogEntry unicode representation

Thanks niko at neagee.net for the report and Emil Stenstrom for
the patch.

comment:8 Changed 3 years ago by Claude Paroz <claude@…>

In 3d4f5f60860051190b11478fd2855c3288f0eab5:

[1.5.x] Fixed #19114 -- Fixed LogEntry unicode representation

Thanks niko at neagee.net for the report and Emil Stenstrom for
the patch.
Backport of e0363c688 from master.

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