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

Django后端报错:union()后调用QuerySet.only()不被支持,求解决方案

Django新手遇到QuerySet.only()在union()后不支持的错误

我是一名Django新手,我的Django后端出现了以下错误:

Calling QuerySet.only() after union() is not supported

触发错误的代码如下:

post_notification_target_users = Post.get_post_comment_notification_target_users(post=post,
                                                                                   post_commenter=post_commenter).only(
        'id', 'username', 'notifications_settings__post_comment_notifications')

查找后发现union()的使用位置:

def get_post_comment_notification_target_users(cls, post, post_commenter):
    """
    Returns the users that should be notified of a post comment.
    This includes the post creator and other post commenters
    :return:
    """

    # Add other post commenters, exclude replies to comments, the post commenter
    other_commenters = User.objects.filter(
        Q(posts_comments__post_id=post.pk, posts_comments__parent_comment_id=None, ) & ~Q(
            id=post_commenter.pk))

    post_creator = User.objects.filter(pk=post.creator_id)

    return other_commenters.union(post_creator)

我查阅了相关帖子,但仍无法找到正确的解决方法。


解决方法

Django里union()返回的QuerySet不支持后续调用only()这类字段过滤方法,原因是UNION要求所有子查询返回的字段数量、类型完全一致,后续没法再修改SELECT的字段列表。这里给两种可行的解决方式:

方式一:在union前给两个子QuerySet指定字段(推荐)

直接把only()的逻辑移到union()之前的两个QuerySet上,保持惰性求值的特性:

def get_post_comment_notification_target_users(cls, post, post_commenter):
    """
    Returns the users that should be notified of a post comment.
    This includes the post creator and other post commenters
    :return:
    """
    # 定义需要的字段
    needed_fields = ('id', 'username', 'notifications_settings__post_comment_notifications')
    
    other_commenters = User.objects.filter(
        Q(posts_comments__post_id=post.pk, posts_comments__parent_comment_id=None) & ~Q(
            id=post_commenter.pk)
    ).only(*needed_fields)

    post_creator = User.objects.filter(pk=post.creator_id).only(*needed_fields)

    return other_commenters.union(post_creator)

之后调用的时候就不用再加only()了:

post_notification_target_users = Post.get_post_comment_notification_target_users(post=post, post_commenter=post_commenter)

方式二:转成列表后手动提取字段(不推荐)

如果一定要在外部处理,可以先把QuerySet转为列表,再提取所需字段,但这样会立即执行数据库查询,失去QuerySet的惰性优势:

users_queryset = Post.get_post_comment_notification_target_users(post=post, post_commenter=post_commenter)
post_notification_target_users = [
    {
        'id': user.id,
        'username': user.username,
        'notifications_settings': user.notifications_settings
    } for user in users_queryset
]

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.19 09:59:53