Graphene-Django中创建Post Mutation返回null问题求助
问题分析与解决方案
核心问题点
- ForeignKey字段赋值错误:Post模型的
author是关联User的ForeignKey,你直接将输入的整数类型用户ID赋值给post.author,不符合Django ForeignKey的赋值规则——需传入User实例,或通过author_id属性直接赋值ID。 - published_date字段参数冲突:模型中
published_date设置了auto_now_add=True,该参数会在对象首次创建时自动设置为当前时间,手动赋值会被覆盖甚至引发赋值异常。 - 异常未捕获:mutate方法无异常处理逻辑,创建Post时出现错误(如用户ID不存在、标题重复)会直接抛出异常,但不会返回明确错误信息,最终导致返回
post: null。
修复步骤
1. 修正CreatePost的mutate方法
修改schema.py中CreatePost类的mutate方法:
@classmethod def mutate(cls, root, info, input): try: # 用author_id直接赋值用户ID,避免实例查询的开销 post = Post( title=input.title, body=input.body, author_id=input.author, status=input.status # 不手动赋值published_date,交给模型的auto_now_add处理 ) # 模型save方法会自动生成slug_title,无需手动赋值 post.save() return CreatePost(post=post) except User.DoesNotExist: raise graphene.GraphQLError("指定的用户不存在") except Exception as e: raise graphene.GraphQLError(f"创建文章失败: {str(e)}")
2. 可选:调整published_date字段(如需手动传入时间)
如果需要创建时手动指定published_date,修改Post模型的字段定义:
# 替换auto_now_add为default,允许手动赋值 published_date = models.DateTimeField(default=timezone.now)
之后可在mutate方法中添加条件赋值:
post = Post( title=input.title, body=input.body, author_id=input.author, status=input.status, published_date=input.published_date if input.published_date else timezone.now() )
3. 优化测试用例
确保测试用例中的用户ID真实存在,建议在测试前创建测试用户:
def setUp(self): # 创建测试用户,ID默认自增为1 self.user = User.objects.create_user(username="testuser", password="testpass") def test_mutation_1(self): response = self.query( ''' mutation { createPost(input:{ title:"Test Title", body:"Test body", author:1, status:false }) { post { title } } } ''' ) self.assertResponseNoErrors(response) # 新增断言,验证文章是否成功创建 self.assertIsNotNone(response.data['create_post']['post'])
4. 移除冗余的slug_title输入
由于Post模型的save方法会自动生成slug_title,可从PostInput中移除该字段,避免输入冲突:
class PostInput(graphene.InputObjectType): title = graphene.String(required=True) # 标记为必填字段 body = graphene.String(required=True) author = graphene.Int(required=True) published_date = graphene.DateTime() status = graphene.Boolean(default=False)
验证修复
执行Mutation请求后,应能正常返回创建的Post对象而非null。若仍有问题,可查看GraphQL响应的errors字段,里面会包含具体错误信息用于进一步排查。
内容的提问来源于stack exchange,提问作者pipocaDourada
相关产品推荐
相关产品推荐

