Django:获取当前用户关注对象的Tweet查询优化咨询
优化建议与改进写法
首先纠正你目标SQL的小错误:你写的子查询SELECT 1 FROM Follower WHERE userFollowing = request.user.id不符合需求,应该改为SELECT userFollowing FROM Follower WHERE user = request.user.id——需要返回被关注用户的ID,而非固定值1,否则只会查询用户ID为1的推文。
基于现有模型的查询优化
你的原有代码是可行的,但可以简化写法,无需拆分两步:
写法1:合并子查询
直接在filter中嵌套子查询,更紧凑:
from django.db.models import Subquery tweets = Tweet.objects.filter( user_id__in=Subquery( Follower.objects.filter(user=request.user.id).values('userFollowing') ) )
写法2:用values_list直接获取ID列表
Django会自动将__in后的列表转换为子查询,写法更直观:
followed_user_ids = Follower.objects.filter(user=request.user.id).values_list('userFollowing', flat=True) tweets = Tweet.objects.filter(user_id__in=followed_user_ids)
模型设计优化(更推荐)
你的Follower模型使用IntegerField存储用户ID,缺乏Django ORM的关联特性。建议改用ForeignKey,既能保证数据完整性(避免无效用户ID),又能支持更简洁的关联查询:
from django.contrib.auth.models import AbstractUser from django.db import models class User(AbstractUser): pass class Follower(models.Model): # 关注者 user = models.ForeignKey(User, on_delete=models.CASCADE, related_name="following") # 被关注者 user_following = models.ForeignKey(User, on_delete=models.CASCADE, related_name="followers") class Meta: # 确保同一用户不会重复关注同一对象 unique_together = ('user', 'user_following') class Tweet(models.Model): user = models.ForeignKey(User, on_delete=models.CASCADE, related_name="tweets") content = models.TextField() date = models.DateTimeField(auto_now_add=True) likes = models.IntegerField(default=0)
优化模型后的查询写法
利用ORM的反向关联,可以写出更简洁高效的查询:
写法1:通过用户的关注记录关联
# 获取当前用户所有关注的用户,再筛选他们的推文 tweets = Tweet.objects.filter(user__in=request.user.following.values('user_following'))
写法2:链式双下划线查询
直接通过反向关联的条件筛选,可读性更强:
# 筛选所有被当前用户关注的用户发布的推文 tweets = Tweet.objects.filter(user__followers__user=request.user)
以上两种写法都会被Django转换为高效的SQL子查询,性能和你的原有实现相当,但代码更简洁、可维护性更高。
内容的提问来源于stack exchange,提问作者waffledood
相关产品推荐
相关产品推荐

