Django REST Framework报错TypeError: 'type' object is not iterable如何解决?
修复 "TypeError: 'type' object is not iterable" 错误的步骤
以下是你的代码中存在的问题及对应的修复方案:
1. models.py 问题修复
问题1:Rating 模型的 Meta 类位置错误
当前 Meta 类独立于 Rating 模型,需移至 Rating 类内部;同时 unique_together 和 index_together 的元组需添加逗号确保为可迭代类型。
问题2:Movie 模型的 avg_rating 方法缩进错误
方法内条件判断和返回语句缩进逻辑错误,导致计算异常。
修复后的 models.py:
from django.db import models from django.contrib.auth.models import User from django.core.validators import MaxValueValidator, MinValueValidator class Movie(models.Model): title = models.CharField(max_length=32) description = models.TextField() def no_of_ratings(self): ratings = Rating.objects.filter(movie=self) return len(ratings) def avg_rating(self): sum_stars = 0 ratings = Rating.objects.filter(movie=self) for rating in ratings: sum_stars += rating.stars if len(ratings) > 0: return sum_stars / len(ratings) else: return 0 class Rating(models.Model): movie = models.ForeignKey(Movie, on_delete=models.CASCADE) user = models.ForeignKey(User, on_delete=models.CASCADE) stars = models.IntegerField(validators=[MinValueValidator(1), MaxValueValidator(5)]) class Meta: unique_together = (('user', 'movie'),) index_together = (('user', 'movie'),)
2. serializers.py 问题修复
问题:导入模块名称拼写错误
将 from rest_framework import serializer 改为 from rest_framework import serializers(复数形式)。
修复后的 serializers.py:
from rest_framework import serializers from .models import Movie, Rating from django.contrib.auth.models import User from rest_framework.authtoken.models import Token class MovieSerializer(serializers.ModelSerializer): class Meta: model = Movie fields = ('id', 'title', 'description', 'no_of_ratings', 'avg_rating') class RatingSerializer(serializers.ModelSerializer): class Meta: model = Rating fields = ('id', 'stars', 'user', 'movie') class UserSerializer(serializers.ModelSerializer): class Meta: model = User fields = ('id', 'username', 'password') extra_kwargs = {'password': {'write_only': True, 'required': True}} def create(self, validated_data): user = User.objects.create_user(**validated_data) Token.objects.create(user=user) return user
3. views.py 问题修复
问题1:认证和权限类未定义为可迭代元组
authentication_classes 和 permission_classes 需要是元组类型,需在末尾添加逗号。
问题2:Serializer 参数拼写错误
mamy=False 改为 many=False。
问题3:rate_movie 方法逻辑错误
- try 块中冗余创建新 Rating 的语句需删除
- 缺少 try 块的返回语句
- 使用 bare except 不够严谨,应捕获特定异常
- 查询 Rating 时无需使用
.id,直接传入实例即可
修复后的 views.py:
from django.shortcuts import render from rest_framework import viewsets, status from .serializers import MovieSerializer, RatingSerializer, UserSerializer from .models import Movie, Rating from rest_framework.response import Response from rest_framework.decorators import action from django.contrib.auth.models import User from rest_framework.authentication import TokenAuthentication from rest_framework.permissions import IsAuthenticated, AllowAny # Create your views here. class UserViewSet(viewsets.ModelViewSet): queryset = User.objects.all() serializer_class = UserSerializer class MovieViewSet(viewsets.ModelViewSet): queryset = Movie.objects.all() serializer_class = MovieSerializer authentication_classes = (TokenAuthentication,) permission_classes = (IsAuthenticated,) @action(detail=True, methods=['POST']) def rate_movie(self, request, pk=None): if 'stars' in request.data: movie = Movie.objects.get(id=pk) stars = request.data['stars'] user = request.user try: rating = Rating.objects.get(user=user, movie=movie) rating.stars = stars rating.save() serializer = RatingSerializer(rating, many=False) response = {'message': 'Rating Updated', 'result': serializer.data} return Response(response, status=status.HTTP_200_OK) except Rating.DoesNotExist: rating = Rating.objects.create(user=user, movie=movie, stars=stars) serializer = RatingSerializer(rating, many=False) response = {'message': 'Rating created', 'result': serializer.data} return Response(response, status=status.HTTP_200_OK) else: response = {'message': 'you need to provide stars'} return Response(response, status=status.HTTP_400_BAD_REQUEST) class RatingViewSet(viewsets.ModelViewSet): queryset = Rating.objects.all() serializer_class = RatingSerializer authentication_classes = (TokenAuthentication,) permission_classes = (AllowAny,) def update(self, request, *args, **kwargs): response = {'message': 'You cant update rating like that'} return Response(response, status=status.HTTP_400_BAD_REQUEST) def create(self, request, *args, **kwargs): response = {'message': 'You cant create rating like that'} return Response(response, status=status.HTTP_400_BAD_REQUEST)
关键错误说明
导致 "TypeError: 'type' object is not iterable" 的核心原因是:
authentication_classes和permission_classes未定义为元组(缺少末尾逗号),Django REST Framework 尝试迭代单个类对象时引发错误。- 其他代码问题(如 Meta 类位置、拼写错误)会进一步导致运行异常。
内容的提问来源于stack exchange,提问作者Itay Lador
相关产品推荐
相关产品推荐

