【问题标题】:How to call OneToOneField reverse relationship in template (django)?如何在模板(django)中调用 OneToOneField 反向关系?
【发布时间】:2021-06-29 23:03:32
【问题描述】:

我的 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]

谢谢:)

【问题讨论】:

  • {{ p.user.first_name }}
  • @khadimhusen 它不工作!
  • 您能否包含您的视图以显示profiles 的定义?
  • 同意,请将视图添加到您的问题中。此外,在这种情况下实际上不需要它,因为这相对简单,但是您始终可以运行 shell python manage.py shell,导入您的 User 或 UserInfo 模型(与视图相同),获取实例(例如u = User.objects.get(pk=1)),然后使用dir(u)查看该对象的所有属性。
  • @markwalker_,请检查编辑...也感谢您的建议

标签: python django model django-templates


【解决方案1】:

正如@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)

所以在这种情况下,您需要使用related_name 引用user 属性。

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

{{ 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 %}

就是这样。

【讨论】:

  • 验证工作正常,但模板仍未加载 first_name,请检查编辑后的版本,谢谢。
  • @RahulNegi 检查更新的信息。我认为您需要使用related_name 来访问onetoone 关系。
  • 我也试过 {{ p.parent_user.first_name }} 但没用! :'( ,它仍然是一个无值。
  • 实际上,验证方法p = UserInfo.objects.first() 工作正常,但显然不适用于p = profiles.objects.first(),因为profiles 只是一个列表,如何在这里实现?
  • 是的,我明白了,我尝试过不使用values(),它工作正常,但是 values('parent_user__first_name') 抛出错误Cannot resolve keyword 'parent_user' into field. Choices are: age, bio, gender, 无论如何我的问题已经解决了,谢谢:)。
猜你喜欢
  • 1970-01-01
  • 2022-06-22
  • 2011-10-04
  • 2016-01-17
  • 1970-01-01
  • 2018-07-05
  • 2019-11-12
  • 1970-01-01
  • 2013-12-07
相关资源
最近更新 更多