You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

无法在Jinja模板中通过变量访问字典值的问题排查

问题描述

在Django项目中,我在views.py的following视图函数里生成了post_likers_ids字典,用来存储帖子ID到点赞用户ID列表的映射,调试确认字典结构为{4: [2], 2: [1,3,5]}。但在following.html的Jinja模板中,循环遍历page_obj里的帖子时,用{% if user.id in post_likers_ids.post_id %}的判断始终不成立。测试发现直接用post_likers_ids.4能正确获取对应值,但通过变量post_id访问却返回空,该怎么解决?


views.py代码

def following(request):
    currentUser = User.objects.get(pk=request.user.id)
    currentUser_followings = Following_System.objects.get(user=currentUser).following
    allPosts = Post.objects.all().order_by("-timestamp").reverse()
    followingPosts = []
    for user in currentUser_followings.all():
        for post in allPosts:
            if post.author == user:
                followingPosts.append(post)
    
    post_likers_ids = {post.id: list(post.likers.values_list('id', flat=True)) for post in followingPosts}

    # 每页显示5条帖子
    paginator = Paginator(followingPosts, 5) 
    page_number = request.GET.get('page')
    page_obj = paginator.get_page(page_number)
    return render(request, "network/following.html",{
        "page_obj": page_obj,
        "post_likers_ids" : post_likers_ids
    })

模板代码(following.html)

{% for post in page_obj %}
<div class="list-group-item">
    {% with post_id=post.id %}
        {% if user.id in post_likers_ids.post_id %}
          <p>该用户已点赞此帖</p>
        {% else %}
          <p>该用户未点赞此帖</p>
        {% endif %}
    {% endwith %}
</div>
{% endfor %}

模型代码(models.py)

class Post(models.Model):
    content = models.TextField(blank=False)
    author = models.ForeignKey("User", on_delete=models.CASCADE, related_name="author")
    timestamp = models.DateTimeField(auto_now_add=True)
    likers = models.ManyToManyField("User", related_name="liked_posts", blank=True)

    def serialize(self):
        likes_count = self.likers.count()
        likers = [user.id for user in self.likers.all()]
        
        return {
            "id": self.id,
            "content": self.content,
            "author": self.author.username,
            "author_id": self.author.id,
            "timestamp": self.timestamp.strftime("%b %d %Y, %I:%M %p"),
            "likes": likes_count,
            "likers" : likers,
        }
class Following_System(models.Model):
    user = models.ForeignKey("User", on_delete=models.CASCADE, related_name="user")
    following = models.ManyToManyField("User", related_name="following")

    def __str__(self):
        return f"User {self.user} is following {', '.join([user.username for user in self.following.all()])}"

解决方案

问题核心是Jinja2模板的字典访问语法错误:

  • post_likers_ids.post_id是在尝试访问字典中键名为字符串"post_id"的值,而非变量post_id对应的键;
  • 直接用post_likers_ids.4生效是因为Jinja2支持点语法访问数字键,但变量必须用方括号语法来访问字典。

修改模板代码

{% for post in page_obj %}
<div class="list-group-item">
    {% if user.id in post_likers_ids[post.id] %}
      <p>该用户已点赞此帖</p>
    {% else %}
      <p>该用户未点赞此帖</p>
    {% endif %}
</div>
{% endfor %}

额外优化建议

  1. 优化视图查询逻辑:替换嵌套循环为ORM过滤,提升性能
# 替换原有followingPosts生成代码
followingPosts = Post.objects.filter(author__in=currentUser_followings.all()).order_by("-timestamp")
  1. 模型层封装判断逻辑:在Post模型中添加方法,简化模板代码
class Post(models.Model):
    # ... 原有字段 ...
    
    def is_liked_by(self, user):
        return self.likers.filter(id=user.id).exists()

模板中直接调用:

{% if post.is_liked_by(user) %}
  <p>该用户已点赞此帖</p>
{% else %}
  <p>该用户未点赞此帖</p>
{% endif %}

内容的提问来源于stack exchange,提问作者Khoa Nguyễn

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.30 10:50:39