相关文章推荐
老实的电梯  ·  使用 REST API 或 Azure ...·  昨天    · 

DRF TypeError 'type' object is not iterable

6 人关注

我正在制作我的第一个DRF api,当我试图使用GET请求访问我的数据时,我得到了一个奇怪的TypeError,我得到了这个错误。

'类型'对象不是可迭代的

下面是一些代码片段。

models.py

from django.db import models
# Create your models here.
class Expediteur(models.Model):
    nom = models.CharField(max_length=50)
    prenom = models.CharField(max_length=100)
    adresse = models.CharField(max_length=200)
    tel = models.IntegerField()

views.py

from django.shortcuts import render, get_object_or_404
from rest_framework import viewsets
from rest_framework.views import APIView
from rest_framework.response import Response
from polls.serializers import ExpediteurSerializer, DestinataireSerializer, LettrePrioSerializer, TypeLettreRecoSerializer, LettreRecoSerializer, TimbrePrioSerializer, TimbreRecoSerializer
from polls.models import Expediteur, Destinataire, LettrePrio, TypeLettreReco, LettreReco, TimbrePrio, TimbreReco
from rest_framework import status, HTTP_HEADER_ENCODING
import json
import datetime
from django.http import HttpResponseRedirect, HttpResponse, Http404
from django.core.urlresolvers import reverse
from django.contrib.auth.decorators import user_passes_test
from django.contrib.auth import login
from django.core.exceptions import ObjectDoesNotExist
from django.views.decorators.csrf import csrf_exempt
from django.utils.timezone import get_current_timezone
from django.db.models.query import QuerySet
# Create your views here.
class ExpeViewSet(APIView):
    QuerySet = Expediteur.objects.all()
    serializer_class = ExpediteurSerializer
    def get(self, request):
        serializer = ExpediteurSerializer(QuerySet, many=True)
        return Response(serializer.data)
    def post(self, request):
        serializer = self.serializer_class(data=request.DATA)
        return Response(status=status.HTTP_201_CREATED)

serializers.py

from rest_framework import serializers
from polls.models import Expediteur, Destinataire, LettrePrio, TypeLettreReco, LettreReco, TimbrePrio, TimbreReco
class ExpediteurSerializer(serializers.ModelSerializer):
    class Meta:
        model = Expediteur

我还留下了Traceback以获得更多信息。

Environment:
Request Method: GET
Request URL: http://0.0.0.0:8000/polls/expediteur/
Django Version: 1.7.1
Python Version: 2.7.6
Installed Applications:
('django.contrib.admin',
 'django.contrib.auth',
 'django.contrib.contenttypes',
 'django.contrib.sessions',
 'django.contrib.messages',
 'django.contrib.staticfiles',
 'rest_framework',
 'polls')
Installed Middleware:
('django.contrib.sessions.middleware.SessionMiddleware',
 'django.middleware.common.CommonMiddleware',
 'django.middleware.csrf.CsrfViewMiddleware',
 'django.contrib.auth.middleware.AuthenticationMiddleware',
 'django.contrib.auth.middleware.SessionAuthenticationMiddleware',
 'django.contrib.messages.middleware.MessageMiddleware',
 'django.middleware.clickjacking.XFrameOptionsMiddleware')
Traceback:
File "/Library/Python/2.7/site-packages/Django-1.7.1-py2.7.egg/django/core/handlers/base.py" in get_response
  111.                     response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/Library/Python/2.7/site-packages/Django-1.7.1-py2.7.egg/django/views/decorators/csrf.py" in wrapped_view
  57.         return view_func(*args, **kwargs)
File "/Library/Python/2.7/site-packages/Django-1.7.1-py2.7.egg/django/views/generic/base.py" in view
  69.             return self.dispatch(request, *args, **kwargs)
File "/Library/Python/2.7/site-packages/rest_framework/views.py" in dispatch
  452.             response = self.handle_exception(exc)
File "/Library/Python/2.7/site-packages/rest_framework/views.py" in dispatch
  449.             response = handler(request, *args, **kwargs)
File "/Users/mehdi/rendu/ProjectWeek/CUP/polls/views.py" in get
  29.         return Response(serializer.data)
File "/Library/Python/2.7/site-packages/rest_framework/serializers.py" in data
  618.         ret = super(ListSerializer, self).data
File "/Library/Python/2.7/site-packages/rest_framework/serializers.py" in data
  213.                 self._data = self.to_representation(self.instance)
File "/Library/Python/2.7/site-packages/rest_framework/serializers.py" in to_representation
  568.             self.child.to_representation(item) for item in iterable
Exception Type: TypeError at /polls/expediteur/
Exception Value: 'type' object is not iterable
    
python
django
Mehdi
Mehdi
发布于 2015-03-19
3 个回答
levi
levi
发布于 2020-05-14
已采纳
0 人赞同

如果你想列出所有 expediteur 的实例,你应该使用 list 视图而不是 get 。记住, get 是用来检索一个实例的。

另外,在你的导入中,你有 from django.db.models.query import QuerySet ,然后当你尝试 ExpediteurSerializer(QuerySet, many=True) 时,你正试图序列化之前导入的 QuerySet 类型。为了得到你定义的 QuerySet ,你需要使用 self. 。但我建议只使用 queryset

class ExpeViewSet(GenericAPIView):
      queryset = Expediteur.objects.all() 
      serializer_class = ExpediteurSerializer
      def list(self,request):
          queryset  = self.Expediteur.objects.all() 
          serializer = ExpediteurSerializer(self.get_queryset(), many=True)
          return Response(serializer.data)
    
谢谢你的回答。我尝试了你给我的代码,但我得到了另一个错误。AtributeError 'ExpeViewSet' object has no attribute 'get_queryset'.
levi
@Mehdi sorry, I fixed, use QuerySet or Expediteur.objects.all()
QuerySet没有被定义,你指的是self.QuerySet,但是QuerySet只会在服务器启动时被评估一次,永远不会被更新。
levi
@user640916 QuerySet被定义了,查看OP代码。但我也把它加成了小写。
levi
@Mehdi啊,那是因为你需要更新你的urls.py添加 list 方法与 GET 请求。
djangonaut
djangonaut
发布于 2020-05-14
0 人赞同

我看到你用了QuerySet,但它应该是小写的。

Try this:

from rest_framework.generics import GenericAPIView
class ExpeViewSet(GenericAPIView):
    queryset = Expediteur.objects.all()  # lowercase!
    serializer_class = ExpediteurSerializer
    def get(self, request):
        serializer = self.serializer_class(self.get_queryset(), many=True)
        return Response(serializer.data)
    
levi
事实上,这不是问题所在。 OP有 from django.db.models.query import QuerySet ,然后他正试图序列化导入的 QuerySet 类型。不是因为小写字母。
你对一个有效的解决方案进行了投票?你给QuerySet分配了一些东西,而QuerySet是一个django的导入,这完全是错误的。你在我的降权投票后编辑了多次。理智一点吧!
levi
编辑你的答案,给你投票,但你也给一个正确的答案投了下票。
prat_bhan
prat_bhan
发布于 2020-05-14
0 人赞同

在我的案例中,我没有从models.Model继承Model。

e.g. class Document: