无法在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 %}
额外优化建议
- 优化视图查询逻辑:替换嵌套循环为ORM过滤,提升性能
# 替换原有followingPosts生成代码 followingPosts = Post.objects.filter(author__in=currentUser_followings.all()).order_by("-timestamp")
- 模型层封装判断逻辑:在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
相关产品推荐
相关产品推荐

