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

使用DRF与django-oauth2-toolkit时出现"type"对象不可迭代错误

解决Django Rest Framework + OAuth2 Toolkit创建用户时的'type' object is not iterable错误

我来帮你搞定这个问题!你遇到的这个'type' object is not iterable错误,大概率是在尝试生成OAuth2访问令牌时,处理返回数据或调用方法的方式不对。咱们一步步来修复:

问题根源分析

你当前的代码只实现了用户创建逻辑,但没有正确集成令牌生成。如果直接在Serializer的create方法里返回令牌对象(而非User实例),DRF后续处理时会尝试迭代这个非可迭代的Token类型对象,从而抛出这个错误——因为DRF期望create方法返回的是模型实例(这里是User)。

解决方案:在View层处理令牌生成

推荐在CreateAPIView的perform_create方法里生成令牌,这样既不破坏Serializer的职责(只负责用户数据序列化),又能正确生成并返回令牌。

修改后的完整代码

Serializer.py(保持原有逻辑即可)

from rest_framework import serializers
from django.contrib.auth.models import User

class UserCreateSerializer(serializers.ModelSerializer):
    def create(self, validated_data):
        user = User.objects.create_user(
            validated_data['username'], 
            validated_data['email'], 
            validated_data['password']
        )
        return user

    class Meta:
        model = User
        fields = ('username', 'email', 'password')

views.py(添加令牌生成逻辑)

from rest_framework.generics import CreateAPIView
from oauth2_provider.models import Application, AccessToken
from django.utils import timezone
from .serializers import UserCreateSerializer
from django.contrib.auth.models import User

class User_Create_view(CreateAPIView):
    serializer_class = UserCreateSerializer
    queryset = User.objects.all()  # 补全缺失的queryset

    def perform_create(self, serializer):
        # 先创建用户
        user = serializer.save()
        # 获取你在Django Admin中创建的OAuth2应用(替换成你的应用名称)
        app = Application.objects.get(name='你的OAuth2应用名称')
        # 生成访问令牌
        access_token = AccessToken.objects.create(
            user=user,
            application=app,
            expires=timezone.now() + timezone.timedelta(hours=24),  # 有效期24小时
            token=AccessToken.generate_token()
        )
        # 暂存令牌数据,后续添加到响应中
        self.token_data = {
            'access_token': access_token.token,
            'expires_in': 86400  # 单位:秒,对应24小时
        }

    def create(self, request, *args, **kwargs):
        # 调用父类方法完成用户创建,拿到基础响应
        response = super().create(request, *args, **kwargs)
        # 将令牌数据添加到响应中返回给前端
        if hasattr(self, 'token_data'):
            response.data.update(self.token_data)
        return response

关键注意事项

  1. 提前创建OAuth2应用:必须先在Django Admin的Applications页面创建一个OAuth2应用,设置合适的client_type(如confidential)和authorization_grant_type(如password),并确保代码中Application.objects.get(name='xxx')的名称和你创建的一致。
  2. 返回正确的实例:Serializer的create方法必须返回User实例,不能返回Token对象,这是DRF的要求,也是避免迭代错误的核心。
  3. 令牌有效期设置:根据你的业务需求调整expires参数,示例中设置的是24小时。

这样修改后,创建用户时会自动生成访问令牌,并将令牌信息包含在响应数据中,同时不会再出现'type' object is not iterable的错误了。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.22 09:57:20