#710 closed enhancement (fixed)
Differentiate between __repr__ and __str__ for model objects
Reported by: | 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 , 19 years ago
Cc: | added |
---|
comment:2 by , 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:7 by , 17 years ago
Reporter: | changed from | to
---|
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).