__str__(self) for ManyToManyField

672 views
Skip to first unread message

Xan

unread,
Nov 8, 2007, 12:11:38 PM11/8/07
to Django users
Hi,

I have these models:

class A(models.Model):

[...]
def __str__(self):
return "(%s, %s)" % (self.estudi, self.curs)


class Admin:
pass

and

class B(models.Model):

estudi_oferit = models.ManyToManyField('A', blank=True, null=True)

class Admin:
list_display = ('tipus', 'codi', 'nom', 'adreca', 'localitat', 'cp',
'zona_concurs', 'ordre_concurs', 'estudi_oferit')

and when I list B elements in admin mode, in puts me address memory of
objects instead of displaying field A as I define in __str__

How can I modify it?
I use 0.96

Thanks in advance,
Xan.

Malcolm Tredinnick

unread,
Nov 8, 2007, 8:36:59 PM11/8/07
to django...@googlegroups.com

You have not defined __str__ on B, so this isn't entirely unexpected
(although I am not completely sure what you're seeing, but anything is
not unexpected here).

Note that the estudi_oferit field is many-to-many, so it has no
"natural" way to be represented as a string. After all, it could be
referring to 10,000 objects at the other end. There's no way to display
that naturally.

Explicitly define a __str__ method on B that displays the fields you
want. Django's default __str__ is rarely the right thing to use.

Regards,
Malcolm

--
The cost of feathers has risen; even down is up!
http://www.pointy-stick.com/blog/

Xan

unread,
Nov 9, 2007, 11:19:59 AM11/9/07
to Django users

On Nov 9, 2:36 am, Malcolm Tredinnick <malc...@pointy-stick.com>
wrote:


> On Thu, 2007-11-08 at 09:11 -0800, Xan wrote:
> > Hi,
>
> > I have these models:
>
> > class A(models.Model):
>
> > [...]
> > def __str__(self):
> > return "(%s, %s)" % (self.estudi, self.curs)
>
> > class Admin:
> > pass
>
> > and
>
> > class B(models.Model):
>
> > estudi_oferit = models.ManyToManyField('A', blank=True, null=True)
>
> > class Admin:
> > list_display = ('tipus', 'codi', 'nom', 'adreca', 'localitat', 'cp',
> > 'zona_concurs', 'ordre_concurs', 'estudi_oferit')
>
> > and when I list B elements in admin mode, in puts me address memory of
> > objects instead of displaying field A as I define in __str__
>
> You have not defined __str__ on B, so this isn't entirely unexpected
> (although I am not completely sure what you're seeing, but anything is
> not unexpected here).
>
> Note that the estudi_oferit field is many-to-many, so it has no
> "natural" way to be represented as a string. After all, it could be
> referring to 10,000 objects at the other end. There's no way to display
> that naturally.

I'mt not agree with you: there is a natural way for displaying
"estudi_oferit": list all of estudi_oferit's that has one instance.

>
> Explicitly define a __str__ method on B that displays the fields you
> want. Django's default __str__ is rarely the right thing to use.

If I put __str__ in B, then I don't use admin list_display (because it
overwrites it).

I consider that I only have to define __str__ in A, not in B, because
I want to display A objects not B. I'm not sure if you understand it?

Thanks in advance,
Xan.

Malcolm Tredinnick

unread,
Nov 10, 2007, 12:01:19 AM11/10/07
to django...@googlegroups.com

Since it's a many-to-many relationship, there could be millions of
related objects for a single B instance, so this would be a very poor
default representation. Django doesn't do that. All your other problems
seem to stem from this assumption. Note that this is actually documented
behaviour, too. You're expecting something to happen that we explicitly
say won't happen (read the docs for list_display again). We also
document how to emulate the behaviour if you really want it.


Malcolm

--
If at first you don't succeed, destroy all evidence that you tried.
http://www.pointy-stick.com/blog/

Xan

unread,
Nov 10, 2007, 2:26:02 PM11/10/07
to Django users

On Nov 10, 6:01 am, Malcolm Tredinnick <malc...@pointy-stick.com>

Yes, but I mean that it should be that way.
We could be restrict the number of objects displaying in admin mode
by:


list_display = ('tipus', 'codi', 'nom', 'adreca', 'localitat',

'cp', 'zona_concurs', 'ordre_concurs', 'estudi_oferit':30)

and admin mode only show almost 30 first objects of estudi_oferit?

It's the natural way for displaying it I think. For the problem of
millions of objects we could put a restriction of displaying in list.
It could be done?


> Django doesn't do that. All your other problems
> seem to stem from this assumption. Note that this is actually documented
> behaviour, too. You're expecting something to happen that we explicitly
> say won't happen (read the docs for list_display again). We also
> document how to emulate the behaviour if you really want it.

Were it's _exactly_ documented? I did not find it

Thanks in advance,
Xan.

Malcolm Tredinnick

unread,
Nov 10, 2007, 7:16:07 PM11/10/07
to django...@googlegroups.com

I've explained why this wouldn't be a good idea (and the documentation
extends that explanation). You want to impose extra database hits and
computation on every single Django user just so that you don't have to
write on extra method. That's not going to happen.

Django provides you with a sensible default and also documents how you
can change this. You really have the best of both worlds here.

Best wishes,
Malcolm

--
If it walks out of your refrigerator, LET IT GO!!
http://www.pointy-stick.com/blog/

Xan

unread,
Nov 11, 2007, 10:55:41 AM11/11/07
to Django users

On Nov 11, 1:16 am, Malcolm Tredinnick <malc...@pointy-stick.com>

Can you pointing me where is the exact location of this documentation?

I think I will change it....

Xan.

Reply all
Reply to author
Forward
0 new messages