Opened 19 years ago

Closed 18 years ago

Last modified 17 years ago

#710 closed enhancement (fixed)

Differentiate between __repr__ and __str__ for model objects

Reported by: Tom Tobin <korpios@…> Owned by: Adrian Holovaty
Component: Core (Other) Version:
Severity: normal Keywords:
Cc: gomo@… Triage Stage: Unreviewed
Has patch: no Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description

The __repr__ method of model objects is currently used for all string representations. The Python documentation states that __repr__ "is typically used for debugging, so it is important that the representation is information-rich and unambiguous." Furthermore, __repr__, when it cannot be used to directly recreate the original object (such as is the case with Django model objects), should return "a string of the form '<...some useful description...>'".

Model objects should differentiate between the __repr__ and __str__ methods. __repr__ should return a string useful for, e.g., identification at a Python interpreter prompt, while __str__ should return a string used in, e.g., template substitution.

Example, for a Topping object in a Pizza app:

class Topping (meta.Model):
    self.name = meta.CharField(maxlength=50)

    def __repr__ (self):
        return '<Topping %s>' % self.name

    def __str__ (self):
        return self.name

As far as I can tell, the Django codebase generally works correctly at this time if one defines both __repr__ and __str__ methods, since the template code uses %s for string interpolation rather than %r. I have not exhaustively checked the Django codebase, however; I do not consider myself familiar enough with it to understand where all the relevant changes would be required, if any. Documentation would need to be updated to reflect this change.

Change History (7)

comment:1 by GomoX <gomo AT datafull DOT com>, 19 years ago

Cc: gomo@… added

This is very interesting. I always found annoying that you couldn't return something decent for the shell from repr, and using it to test queries would return only misleading strings. Having different str() and repr() defs would solve this. I didn't know about this differentiation but it looks very sane and I think this should go in before 1.0, too. Backwards compatibility can be mantained by adding a str() def to django.core.meta.Model that just "return self.repr()"s, and can be overridden by child classes once the documentation and the models are updated. Also, since %s is used all over the place (and not %r), patching shouldn't be too much of a problem.
NEWS: I just checked and BTW (from http://mail.python.org/pipermail/python-dev/2004-May/044881.html), the behaviour I described is the standard Python class behaviour (with repr() also defaulting to str()). So, there isn't even need to do any changes. We should just try updating our models and see what happens (maybe some grep -r "%r" in the trunk, too, just in case).

comment:2 by GomoX <gomo AT datafull DOT com>, 19 years ago

Ok, is guess i misread that post from Guido :/
See http://docs.python.org/ref/customization.html for the correct behaviour. Typically, str() defaults to repr() when it isn't defined, but if str() is defined and repr() is not, Python will just use a typical "<$classname instance at $memaddress>" statement.
From the corresponding part of the documentation, about repr(): This is typically used for debugging, so it is important that the representation is information-rich and unambiguous. I don't think this is the case right now, Django should be using str() for most purposes and automagically provide a classical repr() method (such a SQLObject's) in django.core.meta.Model.

comment:3 by GomoX <gomo AT datafull DOT com>, 19 years ago

See [1042] too.

comment:4 by Tom Tobin <korpios@…>, 18 years ago

Marked #829 as duplicate.

comment:5 by Tom Tobin <korpios@…>, 18 years ago

See #912 regarding documentation of this change.

comment:6 by Adrian Holovaty, 18 years ago

Resolution: fixed
Status: newclosed

Fixed.

comment:7 by korpios, 17 years ago

Reporter: changed from korpios@… to Tom Tobin <korpios@…>
Note: See TracTickets for help on using tickets.
Back to Top