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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.25 15:36:34