Объект 'type' не является итерируемым django-rest-framework
Я новичок в разработке мобильных приложений и пытаюсь сделать свое первое приложение с react-native и Django rest-framework в качестве бэкенда. Когда я пытаюсь запустить сервер и получить доступ к любой модели через django-rest-framework, я получаю "TypeError: 'type' object is not iterable." Я пытался найти способ решения этой проблемы, но все способы, которые я нашел в интернете, не помогли.
Вот мой код:
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 = 0
ratings = Rating.objects.filter(movie=self)
for rating in ratings:
sum += rating.stars
if len(ratings) > 0:
return sum / 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'))
serializers.py-
from rest_framework import serializer
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
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
from rest_framework.permissions import IsAuthenticatedOrReadOnly, BasePermission
# 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.id, movie=movie.id)
rating.stars = stars
rating.save()
serializer = RatingSerializer(rating, mamy=False)
Rating.objects.create(user=user, movie=movie, stars=stars)
response = {'message': 'Rating Updated', 'result': serializer.data}
except:
rating = Rating.objects.create(user=user, movie=movie, stars=stars)
serializer = RatingSerializer(rating, mamy=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)
Как я могу исправить эту ошибку?
authentication_classes
и permission_classes
должны быть кортежами или списками. Когда вы помещаете один класс в скобки, он не будет вести себя с ним как с кортежем, а только как с одним, поэтому не сможет выполнять итерацию над ним.
Измените их следующим образом во всех ваших наборах представлений (поставьте дополнительную запятую после них, чтобы показать python, что эти парантезы демонстрируют кортеж):
#...
authentication_classes = (TokenAuthentication,)
permission_classes = (AllowAny,)
#...