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

Django REST Framework中get_or_create无法设置authUserId属性的问题

问题分析与修复方案

你的SpenderSerializer.create方法存在几个关键问题,导致authUserId始终为空:

1. 错误的用户ID获取方式

Django的User模型实例是对象而非字典,不能用user.get('id')来获取ID,这会直接抛出AttributeError,导致代码进入except分支,authUserId保持为None。

正确写法应该直接访问实例属性:

authUserId = user.id  # 或者 user.pk

2. 邮箱匹配问题(隐性)

你POST的请求数据中邮箱是johndoew@gmail.com,但数据库中User表的对应邮箱是djohndoew@gmail.com(开头多了一个d),这会导致User.objects.get(email=...)抛出User.DoesNotExist异常,同样进入except分支。需要确保请求的邮箱与数据库中的完全一致(注意大小写,Django默认邮箱查询是区分大小写的,除非你修改了字段的db_collation)。

3. get_or_create参数逻辑问题

在你尝试的第二种写法中,将authUserId=authUserId和**validated_data一起作为查询条件传递给get_or_create,这会导致:如果存在邮箱匹配但authUserId为空的Spender记录,会直接返回该记录而不会更新authUserId。正确的做法是把authUserId放在defaults里,仅用邮箱等核心字段作为查询条件。

修复后的完整create方法

def create(self, validated_data):
    authUserId = None
    request_email = validated_data.get("email")
    
    try:
        # 若需要不区分大小写匹配邮箱,可改为 email__iexact=request_email
        user = User.objects.get(email=request_email)
        authUserId = user.id
    except User.DoesNotExist:
        # 明确捕获指定异常,避免捕获所有异常导致的隐藏问题
        pass

    # 用邮箱作为查询条件,其他字段(含authUserId)放入defaults
    return Spender.objects.get_or_create(
        email=validated_data["email"],
        defaults={
            **validated_data,
            'authUserId': authUserId
        }
    )[0]

额外的优化点

  • validate方法中self.instance.name是错误的,你的Spender模型没有name字段,应改为self.instance.email。
  • 避免使用裸except:,明确捕获User.DoesNotExist和MultipleObjectsReturned异常,防止隐藏其他错误。
  • 视图中的queryset多了一个逗号,导致它变成元组,正确写法是queryset = Spender.objects.all()。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.26 02:42:40