使用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
关键注意事项
- 提前创建OAuth2应用:必须先在Django Admin的
Applications页面创建一个OAuth2应用,设置合适的client_type(如confidential)和authorization_grant_type(如password),并确保代码中Application.objects.get(name='xxx')的名称和你创建的一致。 - 返回正确的实例:Serializer的
create方法必须返回User实例,不能返回Token对象,这是DRF的要求,也是避免迭代错误的核心。 - 令牌有效期设置:根据你的业务需求调整
expires参数,示例中设置的是24小时。
这样修改后,创建用户时会自动生成访问令牌,并将令牌信息包含在响应数据中,同时不会再出现'type' object is not iterable的错误了。
内容的提问来源于stack exchange,提问作者sri ganesh
相关产品推荐
相关产品推荐

