9

I have many Models linked to User and I'd like my templates to always display his full_name if available. Is there a way to change the default User __unicode__() ? Or is there another way to do it ?

I have a profile model registered where I can define the __unicode__(), should I link all my models to it ? Seems not a good idea to me.


Imagine I need to display the form for this object

class UserBagde
    user = model.ForeignKey(User)
    badge = models.ForeignKey(Bagde)

I will have to select box with __unicodes__ of each object, won't I ?
How can I have full names in the user's one ?

Pierre de LESPINAY
  • 44,700
  • 57
  • 210
  • 307

4 Answers4

23

Try this:

User.full_name = property(lambda u: u"%s %s" % (u.first_name, u.last_name))

EDIT

Apparently what you want already exists..

https://docs.djangoproject.com/en/dev/ref/contrib/auth/#django.contrib.auth.models.User.get_full_name

ALSO

if its imperative that the unicode function be replaced:

def user_new_unicode(self):
    return self.get_full_name()

# Replace the __unicode__ method in the User class with out new implementation
User.__unicode__ = user_new_unicode 

# or maybe even
User.__unicode__ = User.get_full_name()

Fallback if name fields are empty

def user_new_unicode(self):
    return self.username if self.get_full_name() == "" else self.get_full_name()

# Replace the __unicode__ method in the User class with out new implementation
User.__unicode__ = user_new_unicode 
cgl
  • 1,106
  • 1
  • 13
  • 27
Francis Yaconiello
  • 10,829
  • 2
  • 35
  • 54
  • That's more what I'm searching. Is there somewhere I can put this assignment in order to have it anywhere ? – Pierre de LESPINAY Aug 10 '12 at 13:29
  • put it in the models.py of ANY installed app, I generally have a membership app, that has my profile model, I would put this under that declaration, but that s more personal preference than anything. – Francis Yaconiello Aug 10 '12 at 13:31
  • I agree with the profile location, I'll that thanks. Actually it seems to work even when I don't import the profile model, I don't understand how :) ... – Pierre de LESPINAY Aug 10 '12 at 13:35
  • 1
    you don't have to import any models, just by having the app in your installed apps is enough. – Francis Yaconiello Aug 10 '12 at 13:58
  • how to call this method from view? – A.J. Feb 21 '14 at 11:10
  • you wouldn't probably call the unicode replacement functions directly: `full_name = str(request.user)` gets the unicode string representation of the currently logged in user OR `full_name = request.user.get_full_name()` OR `full_name = request.user.__unicode__()` it really kinda depends on what you are doing. – Francis Yaconiello Feb 21 '14 at 14:16
  • You may mean: https://docs.djangoproject.com/en/2.0/topics/auth/customizing/#django.contrib.auth.models.CustomUser.get_full_name – Antonio Romero Oca Dec 08 '17 at 08:09
  • @AntonioRomero This question/answer was for a much earlier version of Django. The answer above should work for all versions through Django 1.11.x LTS End of Life – Francis Yaconiello Dec 08 '17 at 18:53
  • You are right. But at the given (dev) link there is actually no information about the function `get_full_name` – Antonio Romero Oca Dec 09 '17 at 20:43
3

If you have a profile model set up as Django suggests, you could define the full name on that model

from django.contrib.auth.models import User

class UserProfile(models.Model):
    user = models.OneToOneField(User)
    ...

@property
def full_name(self):
    return "%s %s" % (self.user.first_name, self.user.last_name)

then anywhere you have access to the user object you can easily do user.get_profile.full_name

Alternatively, if you only need the full name in the template you could write a simple tag:

@register.simple_tag
def fullname(user):
    return "%s %s" % (user.first_name, user.last_name)
Timmy O'Mahony
  • 53,000
  • 18
  • 155
  • 177
  • 2
    That's what I'm already doing when I can access to the user object directly (as I said I already have a profile model) but for example in forms when I have to choose from a user in a list, I'll always have usernames displaied – Pierre de LESPINAY Aug 10 '12 at 13:18
1

Just slam get_full_name to the __unicode__ method like so

User.__unicode__ = User.get_full_name

Make sure you override it with the callable, not the result of the function. User.get_full_name() will fail with the open and close brackets.

Place on any included file and you should be good.

Jangita
  • 181
  • 2
  • 6
0

I found there's a quick way to do this in Django 1.5. Check this: custom User models

and I also notice,

User.__unicode__ = User.get_full_name()

which metions by Francis Yaconiello is not work on my side (Django 1.3). Will raise error like this:

TypeError: unbound method get_full_name() must be called with User instance as first argument (got nothing instead)
Too
  • 11
  • 2