如何在Django REST Framework视图中获取已关注用户的全部帖子
获取关注用户全部帖子的Django实现方案
1. 确认基础模型
先确保你的用户关注模型和帖子模型已正确定义:
用户关注模型(基于原方案)
from django.contrib.auth.models import User from django.db import models class Profile(models.Model): user = models.OneToOneField(User, on_delete=models.CASCADE) # 自关联实现关注功能,related_name用于反向查询粉丝列表 following = models.ManyToManyField("self", symmetrical=False, related_name="followers", blank=True) def __str__(self): return self.user.username
帖子模型
class Post(models.Model): author = models.ForeignKey(User, on_delete=models.CASCADE, related_name="posts") content = models.TextField() created_at = models.DateTimeField(auto_now_add=True) class Meta: ordering = ["-created_at"] # 默认按发布时间倒序排列 def __str__(self): return f"{self.author.username}: {self.content[:20]}"
2. 查询关注用户的帖子
在视图中,通过当前用户关联的Profile获取已关注用户,再筛选这些用户发布的帖子:
基础查询写法
from django.shortcuts import render from django.contrib.auth.decorators import login_required from .models import Post, Profile @login_required def following_posts(request): # 获取当前用户的Profile实例 user_profile = Profile.objects.get(user=request.user) # 提取所有关注用户的ID列表 followed_user_ids = user_profile.following.values_list("user__id", flat=True) # 查询这些用户发布的所有帖子,按时间倒序 posts = Post.objects.filter(author__id__in=followed_user_ids).order_by("-created_at") return render(request, "following_posts.html", {"posts": posts})
优化查询(减少数据库请求)
上面的写法会触发两次数据库查询,用prefetch_related可以优化为一次关联查询:
@login_required def following_posts(request): # 预取关注用户的所有帖子,减少数据库查询次数 followed_profiles = request.user.profile.following.all().prefetch_related("user__posts") # 整理所有帖子并按时间排序 posts = [] for profile in followed_profiles: posts.extend(profile.user.posts.all()) # 按发布时间倒序排列 posts.sort(key=lambda x: x.created_at, reverse=True) return render(request, "following_posts.html", {"posts": posts})
3. 模板展示示例
在following_posts.html中循环渲染帖子:
{% extends "base.html" %} {% block content %} <h2>我关注的人发布的动态</h2> {% for post in posts %} <div class="post-card"> <div class="post-author">{{ post.author.username }}</div> <div class="post-content">{{ post.content }}</div> <div class="post-time">{{ post.created_at|date:"Y-m-d H:i" }}</div> </div> {% empty %} <p>你还没有关注任何人,快去关注用户获取动态吧!</p> {% endfor %} {% endblock %}
4. 可选扩展功能
- 分页:使用Django自带的
Paginator实现分页,避免大量帖子加载卡顿 - 实时更新:结合AJAX或WebSocket实现帖子实时推送
- 筛选功能:添加按时间范围、内容关键词等筛选条件
内容的提问来源于stack exchange,提问作者Kelvin Nimely
相关产品推荐
相关产品推荐

