Code

Opened 7 years ago

Closed 7 years ago

#4921 closed (invalid)

django.contrib.admin ignores __str__ on model instances

Reported by: Ludvig Ericson <ludvig.ericson@…> Owned by: adrian
Component: contrib.admin Version: master
Severity: Keywords: admin unicode listing
Cc: Triage Stage: Accepted
Has patch: no Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: UI/UX:

Description

My apologies if this has been reported already -- I did search and couldn't find anything.

django.contrib.admin calls str() on model instances when listing them by default which is not in accordance with the new unicode change, I've defined __unicode__ on my models and not __str__. Note also:

>>> class Foo(object):
...     def __str__(self):
...             return "Normal python str."
... 
>>> unicode(Foo())
u'Normal python str.'

That is, python calls the __str__ method and converts it. Behavior verified in python 2.3, so I see no compatibility issue.

I'd guess I can make up a patch but I'm not sure if this is me being silly or if this actually is an issue.

For now I just do this:

class MyModel(models.Model):
    some_field = models.CharField()
    
    def __unicode__(self):
        return u"foo: %s" % (self.some_field,)
    __str__ = lambda s: str(s.__unicode__())

Attachments (0)

Change History (7)

comment:1 Changed 7 years ago by mtredinnick

  • Needs documentation unset
  • Needs tests unset
  • Patch needs improvement unset

I'm not sure what the bug is here.

Models have a default __str__ method that calls the __unicode__ method, if it exists, and encodes the output correctly (something your temporary fix does not do -- it will break if the result of __unicode__ is non-ASCII). So there shouldn't be any problem at all here.

Are you seeing an actual error? If so, what are the steps to replicate it? Calling str() on a model instance should be quite safe and shouldn be behaving correctly and predictably. We test this in the test suite already.

comment:2 Changed 7 years ago by Ludvig Ericson <ludvig.ericson@…>

I get a lot of XYZ object. Notice that I'm not talking about the models, but the model *instances.*

  1. Create a model with any number of attributes (fields).
  2. Create a ___str___ method on said model, which returns anything you'd like.
  3. Add an empty Admin class.
  4. Create a pair of models of aforementioned model class.
  5. Find the model listing page in the admin for this model. E.g. /admin/foo/

The admin should now say "Foo object" twice.

comment:3 Changed 7 years ago by SmileyChris

  • Summary changed from django.contrib.admin calls str() on model instances, not unicode() to django.contrib.admin ignores __str__ on model instances

Ok, so I *think* what you are saying is that the __str__ method is being ignored in the admin list page?

comment:4 Changed 7 years ago by Ludvig Ericson <ludvig.ericson@…>

Mm, yes, I guess you could put it that way.

Somewhere along the line of Django's meta-programming trickery, Python's default behavior for string representations of objects is changed, which isn't really a bug but it is a tad bit unexpected and inconvenient when you've just merged in trunk which in turn recently merged in the Unicode branch.

comment:5 Changed 7 years ago by Ludvig Ericson <ludvig.ericson@…>

Wait, either I'm being terribly tired (lack of sleep) or I made a mistake in either my comment at 07/19/07 12:49:52 or the summary, because they exclude each other.

I think my comment is wrong, what I probably meant was "define a __unicode__ method" and not __str__.

comment:6 Changed 7 years ago by mtredinnick

  • Triage Stage changed from Unreviewed to Accepted

comment:7 Changed 7 years ago by mtredinnick

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

I don't see the bug here at all. Using this model

from django.db import models
from django.utils.encoding import smart_str

class T4921(models.Model):
    name = models.CharField(maxlength=50)

    def __str__(self):
        return smart_str('foo: %s' % self.name)

    class Admin:
        pass

and following the instructions in comment 2, the right string is displayed in the list view. If I change the __str__ method to a __unicode__ method (and remove the smart_str() bit, obviously), the right string is displayed, because the model's default __str__ calls the __unicode__}} method. If I have both a {{{__str__ and a __unicode__ method defined, the __str__ method is called, but that's intentional: we have to call one or the other, so we pick one (and we pick __str__ so that it's backwards compatible).

So nothing appears to be providing the wrong result. If you provide a __str__ method, it is called; if you only provide a __unicode__ method, it is used. I'm going to close as invalid for now. Please reopen with a concrete example like this one that demonstrates whatever problem you are seeing if you still think there's a bug.

Add Comment

Modify Ticket

Change Properties
<Author field>
Action
as closed
as The resolution will be set. Next status will be 'closed'
The resolution will be deleted. Next status will be 'new'
Author


E-mail address and user name can be saved in the Preferences.

 
Note: See TracTickets for help on using tickets.