Opened 12 years ago

Closed 11 years ago

Last modified 10 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: UI/UX:


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): = meta.CharField(maxlength=50)

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

    def __str__ (self):

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 Changed 12 years ago by GomoX <gomo AT datafull DOT com>

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, 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 Changed 12 years ago by GomoX <gomo AT datafull DOT com>

Ok, is guess i misread that post from Guido :/
See 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 Changed 12 years ago by GomoX <gomo AT datafull DOT com>

See [1042] too.

comment:4 Changed 12 years ago by Tom Tobin <korpios@…>

Marked #829 as duplicate.

comment:5 Changed 12 years ago by Tom Tobin <korpios@…>

See #912 regarding documentation of this change.

comment:6 Changed 11 years ago by Adrian Holovaty

Resolution: fixed
Status: newclosed


comment:7 Changed 10 years ago by korpios

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