首页 > 解决方案 > 如何在模板(django)中调用 OneToOneField 反向关系?

问题描述

我的models.py中有这些模型
User Model

class User(AbstractBaseUser, PermissionsMixin):
    """Custom user model"""
    email = models.EmailField(max_length=255, unique=True)
    first_name = models.CharField(max_length=255)
    last_name = models.CharField(max_length=255)
    is_active = models.BooleanField(default=True)
    is_staff = models.BooleanField(default=False)
    def __str__(self):
        return '{}'.format(self.email)

UserInfo Model

class UserInfo(models.Model):
    """User's Info"""
    user = models.OneToOneField(User, related_name="parent_user", on_delete=models.CASCADE)
    image = models.ImageField(upload_to=user_image_file_path)
    age = models.IntegerField()
    bio = models.CharField(max_length=400)
    def __str__(self):
        return '{}'.format(self.user)

我的模板
在我的模板中,我传递了一些filtered User Profiles(假设按年龄过滤,如果age > 25)现在我还需要显示用户的名称(first_name),但我不知道如何反向调用 OneToOnefield。非常感谢您的帮助:)。

  {% for p in profiles %}
      <div class="profile-container" style="position: relative">
          <div class ="left-div"> 
              <div class="mySlides fade">
                  <img src="media/{{p.image}}" style="width:100%" id="user-media-img">

                  <div class="text">
                      User First Name is : {{`What to type here?`}} 
                  </div>
              </div>
          </div>
          <div class="right-div">
              <div class="details">
                  <h1>BIO</h1>
                  <p>{{p.bio}}</p>
                  <h1>Age:</h1>
                  <p>{{p.age}}</p>
              </div>
          </div>
      </div>
  {% endfor %}

编辑:我的views.py
我正在传递一个名为配置文件的列表,该列表已根据 2-3 种不同类型的过滤器过滤配置文件,因此代码将太多,无法在此处粘贴所有参考资料,我在此处粘贴简短版本:

start =18
end=25
 matching = UserInfo.objects.filter(
        age__gte=start, age__lte=end
    ).values()

    for z in matching:
        if z['user_id'] not in rec_ids:
            profiles.append(z)
    print('profiles====', profiles)

 context = {
        'profiles' : profiles,
    }

    return render(request, 'home/news.html', context)

在此处粘贴输出

profiles==== [{'id': 18, 'user_id': 8, 'image': 'uploads/user/image/9d096190-73a0-4885-b4cd-ef6c7229b9eb.png', 'age': 23, 'bio': 'cool'}..etc]

谢谢 :)

标签: pythondjangomodeldjango-templates

解决方案


正如@khadim hussen 在评论中所写,您应该使用以下语法:

p.user.first_name

p您的UserInfo模型在哪里,并且p.user是对 OneToOne 关系的参考。

请注意,当您没有与 p -> user 相关的用户时,您将返回的值为None.

如果您想显示与None模板不同的信息,只需执行以下验证:

{% if p.user is not None %}
    {{p.user}}
{% else %}
    Without User
{% endif %}

但是在您的观点中,您将获得一个RelatedObjectDoesNotExists以确保在您的观点中存在关系,您可以进行以下验证:

p = UserInfo.objects.first()
if hasattr(p, 'user'):
   user = p.user

另一件重要的事情是当你有一个 related_name 属性时,如你的示例所示:

user = models.OneToOneField(User, related_name="parent_user", on_delete=models.CASCADE)

因此,在这种情况下,您需要user使用related_name.

以更具体的方式,您必须执行以下操作:

{{ p.parent_user.first_name }}

一件重要的事情是,如果您正在使用queryset.filter(...).values(),那么如果您想从其他模型加载值,您可以使用以下内容:

queryset.filter(...).values('image','age','bio','user','parent_user__first_name',...)
``
And in your template:
```python
{% p.parent_user__first_name %}

就是这样。


推荐阅读