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

Django如何通过多模型关注对象列表过滤GenericForeignKey获取用户动态

问题原因

你之前的写法报错是因为GenericForeignKey是Django层面封装的虚拟字段,数据库中不存在对应的实际存储字段,无法直接使用actor__in这类跨关系查询语法,必须通过它绑定的两个实际数据库字段xxx_content_type和xxx_object_id来筛选。

实现代码

你可以将关注的对象按内容类型分组后拼接查询条件,一次性查出所有符合要求的动态:

from django.db.models import Q

# 先按内容类型分组,存储所有关注对象的id
follow_groups = {}
for follow in thor.follow_set.all():
    ct_id = follow.content_type_id
    if ct_id not in follow_groups:
        follow_groups[ct_id] = []
    follow_groups[ct_id].append(follow.object_id)

# 构造总查询条件
query = Q()
for ct_id, obj_ids in follow_groups.items():
    # 匹配:该对象作为活动的发起者
    query |= Q(actor_content_type_id=ct_id, actor_object_id__in=obj_ids)
    # 匹配:该对象作为活动的作用目标
    query |= Q(target_content_type_id=ct_id, target_object_id__in=obj_ids)

# 执行查询,distinct去重,按id倒序就是按时间从新到旧排序
thor_activities = Activity.objects.filter(query).distinct().order_by('-id')

执行后得到的结果就包含你需要的三条动态。

优化方案(可选)

如果这个查询场景使用频率很高,可以封装为Activity模型的管理器方法,后续调用更简洁:

  1. 先定义自定义管理器
from django.db.models import Q, Manager

class ActivityManager(Manager):
    def get_follow_activities_by_user(self, user):
        follow_groups = {}
        for follow in user.follow_set.all():
            follow_groups.setdefault(follow.content_type_id, []).append(follow.object_id)
        query = Q()
        for ct_id, obj_ids in follow_groups.items():
            query |= Q(actor_content_type_id=ct_id, actor_object_id__in=obj_ids)
            query |= Q(target_content_type_id=ct_id, target_object_id__in=obj_ids)
        return self.filter(query).distinct().order_by('-id')
  1. 给Activity模型绑定管理器
class Activity(models.Model):
    # 原有字段不变
    objects = ActivityManager()
  1. 后续直接调用即可
thor_activities = Activity.objects.get_follow_activities_by_user(thor)

内容的提问来源于stack exchange,提问作者Msw Tm

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.06 21:27:01