Proposal: make Model __unicode__() default to self.name

353 views
Skip to first unread message

cmawe...@gmail.com

unread,
Jul 10, 2013, 11:46:25 PM7/10/13
to django-d...@googlegroups.com
Hi All,

Have you ever quickly set up a model, ran syncdb, and added a few sample objects in the admin to only see a bunch of "MyModel object"s in the changelist? I always forget to add a __unicode__()/__str__() method on my models.

I ran "git grep -1 __unicode__" on some of my django projects and noticed a lot of repeated code. In fact, it seems that in about a _third_ of all my cases, I'm just returning self.name, or returning self.name would have been a good default. I looked at a few 3rd party apps for comparison and found similar results, though not for every app.

IMHO, returning self.name (if the field or property exists) is a sensible default for __unicode__. We can still return "MyModel object" if there's no "name" attribute. You'll still end up adding your own __unicode__ method much of the time, just like you always have.

Yes, it's "magic", but we can document it.
Yes, it's a little more confusing, but we don't have to explain it during the tutorial.
Yes, it's backwards incompatible, but only in rare cases should it be a problem.
Yes, it could look like any Model without a "name" field is "wrong", but it's not.
Yes, "title" is also very popular, but name is better. :)

It has the effect of being a little more friendly in many cases, and can result in more DRY code.

What do your __unicode__/__str__ methods look like? Is this a bad idea?

Thanks,
Collin

Luke Sneeringer

unread,
Jul 10, 2013, 11:51:09 PM7/10/13
to django-d...@googlegroups.com
What makes “name” special. Why not “label”, “title”, “code”, or any number of other things that people use internally?

It also seems like you could solve this very easily by creating a stub model:

    from django.db import models

    class MyModel(models.Model):
        class Meta:
            abstract = True

        def __unicode__(self):
            return self.name

This has the advantage of your not having to repeat yourself often (and it gives you another place to put your own particular things which you consistently practice), while not becoming opinionated about a naming scheme across the entire framework.

Best Regards,
Luke Sneeringer

P. S. A place where I *would* love to see a better Django default would be in the __repr__ method.

-- 
You received this message because you are subscribed to the Google Groups "Django developers" group.
To unsubscribe from this group and stop receiving emails from it, send an email to django-develop...@googlegroups.com.
To post to this group, send email to django-d...@googlegroups.com.
Visit this group at http://groups.google.com/group/django-developers.
For more options, visit https://groups.google.com/groups/opt_out.

Curtis Maloney

unread,
Jul 11, 2013, 12:01:01 AM7/11/13
to django-d...@googlegroups.com
Luke beat me to it...

We have a couple of abstract models which will fall through a small list of field names, trying to guess a useful default for __str__ ... but it makes me feel dirty every time I see it.

Beyond "blessing" a particular (set of?) field names as default str names... this also adds more magic, and the trend I'm seeing now in the IRC channel is people are believing too much in magic.

Just my 0.0000000152 bitcoins...

--
Curtis

Aymeric Augustin

unread,
Jul 11, 2013, 2:33:08 AM7/11/13
to django-d...@googlegroups.com
On 11 juil. 2013, at 05:46, cmawe...@gmail.com wrote:

> What do your __unicode__/__str__ methods look like? Is this a bad idea?

In addition to the previous answers, I find it important to have an unambiguous __unicode__ / __str__, and name isn't necessarily unique.

--
Aymeric.

mjl Martin J. Laubach

unread,
Jul 11, 2013, 8:41:42 AM7/11/13
to django-d...@googlegroups.com
> In addition to the previous answers, I find it important to have an unambiguous __unicode__ / __str__, and name isn't necessarily unique.

  Perhaps to have it a tiny little bit more useful, have it default to "MyModel object (object_pk)" ?

        mjl

Aymeric Augustin

unread,
Jul 11, 2013, 10:57:34 AM7/11/13
to django-d...@googlegroups.com
2013/7/11 mjl Martin J. Laubach <goo...@emsi.priv.at>
 
Perhaps to have it a tiny little bit more useful, have it default to "MyModel object (object_pk)" ?

I could support that. object_pk will be None when the object isn't saved yet, but that's fine.

--
Aymeric.

Shai Berger

unread,
Jul 11, 2013, 11:29:33 AM7/11/13
to django-d...@googlegroups.com
So if we're already doing that, take the extra step and make it "MyModel
object (unsaved)" in that case.

Kapil Garg

unread,
Apr 2, 2017, 11:12:58 AM4/2/17
to Django developers (Contributions to Django itself)
Ticket 27953 is regarding this proposal and the suggestion is about adding "pk" in Model string representation if it exists. 

Collin Anderson

unread,
Apr 2, 2017, 2:17:01 PM4/2/17
to django-d...@googlegroups.com
Makes sense to me. Maybe still keep the "Transaction object" part, and use None if no pk.

--
You received this message because you are subscribed to the Google Groups "Django developers (Contributions to Django itself)" group.
To unsubscribe from this group and stop receiving emails from it, send an email to django-developers+unsubscribe@googlegroups.com.
To post to this group, send email to django-developers@googlegroups.com.
Visit this group at https://groups.google.com/group/django-developers.
To view this discussion on the web visit https://groups.google.com/d/msgid/django-developers/c7254a96-7ee3-4262-a90b-83dcfe8fa3d4%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Kapil Garg

unread,
Apr 3, 2017, 1:06:54 PM4/3/17
to Django developers (Contributions to Django itself)
So what should the final __str__ show: Should it be 'ClassName object pk=Something' and if pk is None then should it be 'ClassName object (unsaved)' or 'ClassName object pk=None' ?


On Sunday, 2 April 2017 23:47:01 UTC+5:30, Collin Anderson wrote:
Makes sense to me. Maybe still keep the "Transaction object" part, and use None if no pk.
On Sun, Apr 2, 2017 at 11:09 AM, Kapil Garg <kapilg...@gmail.com> wrote:
Ticket 27953 is regarding this proposal and the suggestion is about adding "pk" in Model string representation if it exists. 

On Thursday, 11 July 2013 09:16:25 UTC+5:30, Collin Anderson wrote:
Hi All,

Have you ever quickly set up a model, ran syncdb, and added a few sample objects in the admin to only see a bunch of "MyModel object"s in the changelist? I always forget to add a __unicode__()/__str__() method on my models.

I ran "git grep -1 __unicode__" on some of my django projects and noticed a lot of repeated code. In fact, it seems that in about a _third_ of all my cases, I'm just returning self.name, or returning self.name would have been a good default. I looked at a few 3rd party apps for comparison and found similar results, though not for every app.

IMHO, returning self.name (if the field or property exists) is a sensible default for __unicode__. We can still return "MyModel object" if there's no "name" attribute. You'll still end up adding your own __unicode__ method much of the time, just like you always have.

Yes, it's "magic", but we can document it.
Yes, it's a little more confusing, but we don't have to explain it during the tutorial.
Yes, it's backwards incompatible, but only in rare cases should it be a problem.
Yes, it could look like any Model without a "name" field is "wrong", but it's not.
Yes, "title" is also very popular, but name is better. :)

It has the effect of being a little more friendly in many cases, and can result in more DRY code.

What do your __unicode__/__str__ methods look like? Is this a bad idea?

Thanks,
Collin

--
You received this message because you are subscribed to the Google Groups "Django developers (Contributions to Django itself)" group.
To unsubscribe from this group and stop receiving emails from it, send an email to django-develop...@googlegroups.com.
To post to this group, send email to django-d...@googlegroups.com.

Collin Anderson

unread,
Apr 3, 2017, 1:37:56 PM4/3/17
to django-d...@googlegroups.com
I'd recommend not saying "unsaved". "new" if anything. UUID pk's may default to generating a pk before save, so it might just be best to show the actual current pk value

To unsubscribe from this group and stop receiving emails from it, send an email to django-developers+unsubscribe@googlegroups.com.
To post to this group, send email to django-developers@googlegroups.com.

Kapil Garg

unread,
Apr 3, 2017, 4:07:47 PM4/3/17
to Django developers (Contributions to Django itself)
So does this patch seem fine ? 

diff --git a/django/db/models/base.py b/django/db/models/base.py
index 3c1cb9a..f58e12b 100644
--- a/django/db/models/base.py
+++ b/django/db/models/base.py
@@ -504,7 +504,7 @@ class Model(metaclass=ModelBase):
         return '<%s: %s>' % (self.__class__.__name__, u)
 
     def __str__(self):
-        return '%s object' % self.__class__.__name__
+        return '%s object pk=%s' % (self.__class__.__name__, self._get_pk_val())
 
     def __eq__(self, other):
         if not isinstance(other, Model):

Marco Silva

unread,
Apr 7, 2017, 9:22:31 AM4/7/17
to Django developers (Contributions to Django itself)
I noticed this on the init
def __init__(self, *args, **kwargs):
 
# Alias some things as locals to avoid repeat global lookups
 cls
= self.__class__
maybe you should change it to self.cls??
Try to submit a PR to the open ticket.

Kapil Garg

unread,
Apr 7, 2017, 10:34:32 AM4/7/17
to Django developers (Contributions to Django itself)

The opened ticket is about Model.__str__ method. Should i open a new ticket for this change ?
As i see in code, self.__class__ is used in a lot of places but will it effect optimization if we change lookups from self.__class__ to self.cls

Because the methods where class is being used frequently, already store it in local variable and then make references to local variable.

So should it really be changed ?


You received this message because you are subscribed to a topic in the Google Groups "Django developers (Contributions to Django itself)" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/django-developers/7Jqzwg5nt-c/unsubscribe.
To unsubscribe from this group and all its topics, send an email to django-develop...@googlegroups.com.

To post to this group, send email to django-d...@googlegroups.com.
Visit this group at https://groups.google.com/group/django-developers.

Collin Anderson

unread,
Apr 7, 2017, 10:58:52 AM4/7/17
to django-d...@googlegroups.com
Hi All,

Looking at the code snippet, cls is a _local_ variable, not an instance attribute (self.cls). If we changed it to an instance attribute, it would lose most of the speed optimization. Also, self.cls would possibly clash with a field named "cls".

Collin


To unsubscribe from this group and all its topics, send an email to django-developers+unsubscribe@googlegroups.com.
To post to this group, send email to django-developers@googlegroups.com.

--
You received this message because you are subscribed to the Google Groups "Django developers (Contributions to Django itself)" group.
To unsubscribe from this group and stop receiving emails from it, send an email to django-developers+unsubscribe@googlegroups.com.
To post to this group, send email to django-developers@googlegroups.com.

is_null

unread,
Apr 8, 2017, 6:25:54 AM4/8/17
to Django developers (Contributions to Django itself)
Usually people tell me that type(self) is better than self.__class__, so you might prepare to change that too.

But yeah, it seems like a very reasonable change to me, reading lists of indistinct <Model object> have always required extra steps to figure out what models they are.

Thanks for your effort,
Best
James

Marco Silva

unread,
Apr 8, 2017, 12:06:05 PM4/8/17
to Django developers (Contributions to Django itself)
I have no idea what is the best way, just say that comment. this is the original PR

I think you should submit the PR to change the __str__ method, and maybe open a new discussion regarding __repr__

Marco Silva

unread,
Apr 8, 2017, 12:08:29 PM4/8/17
to Django developers (Contributions to Django itself)
just saw that __repr__ is now under discusion here

Collin Anderson

unread,
Apr 8, 2017, 2:41:56 PM4/8/17
to django-d...@googlegroups.com
I just made a pull request.

(1) is my first choice, pk=1 is my second choice. I'd be fine with either.

To unsubscribe from this group and stop receiving emails from it, send an email to django-developers+unsubscribe@googlegroups.com.
To post to this group, send email to django-developers@googlegroups.com.

Alex Corcoles

unread,
Dec 11, 2017, 7:11:29 AM12/11/17
to Django developers (Contributions to Django itself)
Sorry to resurrect this, but I commented on the bug tracker ( https://code.djangoproject.com/ticket/28839#comment:4 ) and was told to take the discussion here.

I want to point out that __str__ is used for "GUI" purposes (such as dropdown texts in ModelForm/ModelAdmin) and putting a default __str__ with a PK doesn't seem to make sense. I think __str__ is a more user/human-friendly thing, which I don't think can be generated automatically.

On the other hand, it does make sense to include the PK in __repr__, so I would suggest backtracking on this change and making an equivalent change in __repr__.

Collin Anderson

unread,
Dec 12, 2017, 9:48:38 AM12/12/17
to django-d...@googlegroups.com
Hi Alex,

> I think __str__ is a more user/human-friendly thing, which I don't think can be generated automatically.

Yes, having a good __str__ is important, and thats why i think defaulting it to the pk is good, because it's better than nothing. Yes, you'll still want to override __str__ with something better (that likely doesn't include the PK).

So if you're overriding __str__ anyway, why not also override __repr__ to include the PK?

Or what are you actually proposing, something like this?

Thanks,
Collin




To unsubscribe from this group and stop receiving emails from it, send an email to django-developers+unsubscribe@googlegroups.com.
To post to this group, send email to django-developers@googlegroups.com.

Alex Corcoles

unread,
Dec 12, 2017, 10:00:17 AM12/12/17
to Django developers (Contributions to Django itself)
Hi Collin,


On Tuesday, December 12, 2017 at 3:48:38 PM UTC+1, Collin Anderson wrote:
Yes, having a good __str__ is important, and thats why i think defaulting it to the pk is good, because it's better than nothing. Yes, you'll still want to override __str__ with something better (that likely doesn't include the PK).

I slightly disagree on this specific point, but I don't think my squabble is worth wasting anyone's time :)

So if you're overriding __str__ anyway, why not also override __repr__ to include the PK?

Or what are you actually proposing, something like this?
 
Yeah, I just want something like your PR. I want to override __str__ most of the time, so having it include the PK doesn't do much for me- neither good or bad, but having the default __repr__ include the PK saves me from overriding it most of the time.

I could nitpick on my ideal implementation of both methods, but I think it comes down to personal taste so I just wanted to propose having PK in the default __repr__ implementation as I think that will benefit people. The rest doesn't matter that much to me.

Thank you,

Álex

Reply all
Reply to author
Forward
0 new messages