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
相关产品推荐
相关产品推荐

