Django Template how to get the value of a model through the OneToOneField

Question:

In my Django App i have Two Models and the User model from django.contrib.auth.models

from django.contrib.auth.models import User

class Room(models.Model):
    host = models.ForeignKey(User, on_delete=models.CASCADE, null=True) 
    topic = models.ForeignKey(Topic, on_delete=models.SET_NULL, null=True)
    name = models.CharField(max_length=200)
    description = models.TextField(null = True, blank = True)
    participants = models.ManyToManyField(User, related_name='participants', blank = True)
    updated = models.DateTimeField(auto_now=True)
    created = models.DateTimeField(auto_now_add=True)

    class Meta:
        ordering = ['-updated', '-created']

    def __str__(self):
        return self.name

class UserProfile(models.Model):
    user = models.OneToOneField(User, on_delete=models.CASCADE)
    name = models.CharField(max_length=50)
    about = models.TextField(max_length=250)
    avatar = models.ImageField(upload_to='avatars')

    def __str__(self):
        self.user.username

In my template i’m looping through objects of a Room list and i need to get the value avatar from UserPorfile

{% for room in rooms %}
<div class="roomListRoom">
    <div class="roomListRoom__header">
        <a href="{% url 'user-profile' room.host.id %}" class="roomListRoom__author">
        <div class="avatar avatar--small">
           <img src="" /> <!-- This image should refer to the UserProfile linked to room.host-->
        </div>
        <span>@{{room.host.username}}</span>
        </a>
        <div class="roomListRoom__actions">
        <span>{{room.created|timesince}}</span>
        </div>
    </div>
</div>

Can i do this? If i can, how? Can i solve this problem in a better way?

Asked By: lopesvictor1

||

Answers:

Assuming you are passing rooms in a a context variable to cycle through, you should be able to refer to the URL field directly (as per the docs)

{{ room.host.avatar.url }}

or in your case

<img src="{{ room.host.avatar.url }}" />

As a side note, to reduce database calls, you may want to grab the host details when you select your list of rooms, eg,

roooms = Room.objects.filter(x=y).select_related('host')

Otherwise every time you look for the URL in your rooms loop, you’ll need to make another db call to grab the host details.

Answered By: SamSparx

You should retrive the avatar from user profile in views.py, then send to html via context.

code should be in views.py

avatar = request.user.userprofile.avatar 
context = {
'avatar ': avatar  
}
Answered By: Vinay Vishwakarma