Extending the user model and accessing fields in template context

80 views
Skip to first unread message

Bernd Wechner

unread,
Jun 7, 2017, 6:47:36 PM6/7/17
to Django users

Have failed to find an easy answer to this so will lazily ask the broader community before I retire tonight ;-).

I have a model that I use to extend the User model like yo:

from django.contrib.auth.models import User

class Dude(models.Model):
    nickname = models.CharField('Nickname', max_length=MAX_NAME_LENGTH)
    clans = models.ManyToManyField('League', blank=True, related_name='dudes_in_clan')
    user = models.OneToOneField(User, related_name='dude', blank=True, null=True, default=None)

Now  {{ user }} renders as the user name quite well in my templates so I can show the logged in user in a header. Nice.

But I'd like to access fields in the extended model like {{ user.dude.nickname }}.

Alas, it's not that simple clearly. I'm missing something, as that renders blank.

The Django Toolbar is not very helpful in drilling down as it only lists:

'user': <SimpleLazyObject: <User: me>>

and reveals nothing about the . notation elements of user that I might be able to access. I can access all the fields  of the User model like {{ user.date_joined }} works fine. But the related_name of the OneToOne relationship isn't working as I'd have hoped.

Is there a trick I'm missing?

Regards,

Bernd.



Melvyn Sopacua

unread,
Jun 7, 2017, 7:25:15 PM6/7/17
to django...@googlegroups.com

On Thursday 08 June 2017 08:46:38 Bernd Wechner wrote:

> Have failed to find an easy answer to this so will lazily ask the

> broader community before I retire tonight ;-).

>

> I have a model that I use to extend the User model like yo:

>

> from django.contrib.auth.models import User

>

> class Dude(models.Model):

> nickname = models.CharField('Nickname',

> max_length=MAX_NAME_LENGTH) clans = models.ManyToManyField('League',

> blank=True, related_name='dudes_in_clan')

> user = models.OneToOneField(User, related_name='dude',

> blank=True, null=True, default=None)

>

> Now {{ user }} renders as the user name quite well in my templates so

> I can show the logged in user in a header. Nice.

>

> But I'd like to access fields in the extended model like {{

> user.dude.nickname }}.

>

> Alas, it's not that simple clearly. I'm missing something, as that

> renders blank.

 

If there is no profile, an exception is thrown. It throws a rather useless exception RelatedObjectDoesNotExist, cause to catch it, you'd have to reference the accessor, which will throw RelatedObjectDoesNotExist and to catch it ... etc.

 

You can however catch it as an AttributeError, then inspect it's type. See: django.db.models.fields.related_descriptors.ReverseOneToOneDescriptor

 

In templates exceptions are caught and silenced and the empty string is returned.

 

So to prevent a disconnect between a User model and a profile model, you basically have to make sure, that whenever a new User is created, you create a new profile. This is why typically, all fields in a profile model have null=True, so that you can listen to the post_save signal on the User model and create a profile, without requiring profile information.

 

It's either that, or you have to augment the things in your project that create users with the required profile data. By default that is the admin and the createsuperuser command.

--

Melvyn Sopacua

Bernd Wechner

unread,
Jun 7, 2017, 11:17:39 PM6/7/17
to django...@googlegroups.com
Why thank you Melvyn, nailed it one. I had assumed there was a profile connected but alas it was not set ... once I set it, the template access through the dot notation to the profile works fine. It is the silent exception being ignored that threw me  guess. Arguably appropriate response to a lacking profile of course, but I'd sort of prefer to be informed too. Still, if it wasn't already so late at night when it hit me, I might have thought to examine the link in the models and database to ensure that I've set the user field in the Dude model ;-).

Regards,

Bernd.

Melvyn Sopacua wrote:
--
You received this message because you are subscribed to the Google Groups "Django users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to django-users...@googlegroups.com.
To post to this group, send email to django...@googlegroups.com.
Visit this group at https://groups.google.com/group/django-users.
To view this discussion on the web visit https://groups.google.com/d/msgid/django-users/2020313.dh1SZzXWp7%40devstation.
For more options, visit https://groups.google.com/d/optout.


Reply all
Reply to author
Forward
0 new messages