Django 'ModelBase' objeto no es iterable TipoError
Consiguiendo lo siguiente de una prueba de unidad en Django. No puedo imaginar la razón por la que esto está pasando.
Mis migraciones parecen idénticas a las otras migraciones que he hecho.
Además, fui capaz de ejecutar esto en mi máquina local en la sección de administración, así que mi otra pregunta es esta gran cosa si está sucediendo durante la prueba si puede ser empujado en vivo. Intentando seguir las mejores prácticas aquí, así que aprecia las opiniones de otros sobre eso.
modelos. py
class LeadComplete(models.Model):
"""Complete lead info"""
user = models.ForeignKey(
settings.AUTH_USER_MODEL,
on_delete=models.DO_NOTHING,
)
title=models.CharField(max_length=255)
time_minutes = models.IntegerField()
score = models.DecimalField(max_digits=5, decimal_places=2)
link = models.CharField(max_length=255, blank=True)
client = models.ManyToManyField('Client')
def __str__(self):
return self.title
serializadores.py
class LeadCompleteSerializer(serializers.ModelSerializer):
"""Serialize a leadComplete"""
client = serializers.PrimaryKeyRelatedField(
many=True,
queryset=Client.objects.all()
)
class Meta:
model = LeadComplete
fields = [
'id', 'title', 'time_minutes', 'score', 'link', 'client',
]
read_only_fields = ('id',)
vistas. py
class LeadCompleteViewSet(viewsets.ModelViewSet):
"""Manage LeadComplete in the database"""
serializer_class = serializers.LeadCompleteSerializer
queryset = LeadComplete.objects.all()
authentication_classes = (TokenAuthentication,)
permission_classes = (IsAuthenticated,)
def get_queryset(self):
"""Retrieve the leadcomplete for the authed user"""
return self.queryset.filter(user=self.request.user)
test_lead_complete_api.py
from django.contrib.auth import get_user_model
from django.test import TestCase
from django.urls import reverse
from rest_framework import status
from rest_framework.test import APIClient
from core. models import LeadComplete
from leads.serializers import LeadCompleteSerializer
LEADCOMPLETE_URL = reverse('leads:leadcomplete-list')
def sample_leadComplete(user, **params):
"""Create and return a sample leadComplete"""
defaults = {
'title': 'Samle Company',
'time_minutes': 10,
'score': 5.00,
}
defaults.update(params)
return LeadComplete.objects.create(user=user, **defaults)
def PublicLeadCompleteApiTests(TestCase):
"""Test unauthenticated LeacComplete access"""
def setUp(self):
self.client = APIClient()
def test_auth_required(self):
""""Test that authentication is required"""
res = selft.client.get(LEADCOMPLETE_URL)
self.assertEqual(res.status_code, status.HTTP_401_UNAUTHORIZED)
class PrivateLeadCompleteApiTests(TestCase):
""""Test authenticated recipe API access"""
def setUp(self):
self.client = APIClient()
self.user = get_user_model().objects.create_user(
'[email protected]',
'testpass'
)
self.client.force_authenticate(self.user)
def test_retrieve_leadComplete(self):
"""Test retrieving LeadComplete list"""
sample_leadComplete(user=self.user)
sample_leadComplete(user=self.user)
res = self.client.get(LEADCOMPLETE_URL)
leadComplete = LeadComplete.objects.all().order_by('-id')
serializer = LeadCompleteSerializer(LeadComplete, many=True)
self.assertEqual(res.status_code, status.HTTP_200_OK)
self.assertEqual(res.data, serializer.data)
def test_leadComplete_limited_to_user(self):
"""Test retrieving leadComplete for user"""
user2 = get_user_model().objects.create_user(
'[email protected]',
'password123'
)
sample_leadComplete(user=user2)
sample_leadComplete(user=self.user)
res = self.client.get(LEADCOMPLETE_URL)
leadComplete = LeadComplete.objects.filter(user=self.user)
serializer = LeadCompleteSerializer(leadComplete, many=True)
self.assertEqual(res.status_code, status.HTTP_200_OK)
self.assertEqual(res.data, serializer.data)
error:
ERROR: test_retrieve_leadComplete (leads.tests.test_leadcomplete_api.PrivateLeadCompleteApiTests)
Test retrieving LeadComplete list
----------------------------------------------------------------------
Traceback (most recent call last):
File "/app/leads/tests/test_leadcomplete_api.py", line 58, in test_retrieve_leadComplete
self.assertEqual(res.data, serializer.data)
File "/usr/local/lib/python3.7/site-packages/rest_framework/serializers.py", line 768, in data
ret = super(ListSerializer, self).data
File "/usr/local/lib/python3.7/site-packages/rest_framework/serializers.py", line 262, in data
self._data = self.to_representation(self.instance)
File "/usr/local/lib/python3.7/site-packages/rest_framework/serializers.py", line 686, in to_representation
self.child.to_representation(item) for item in iterable
TypeError: 'ModelBase' object is not iterable
Pregunta hecha hace 3 años, 4 meses, 29 días - Por cyberjedi
3 Respuestas:
-
El cliente de prueba devuelve datos en la propiedad de contenido.
Prueba.
res.content
en lugar deres.data
def test_retrieve_leadComplete(self): """Test retrieving LeadComplete list""" sample_leadComplete(user=self.user) sample_leadComplete(user=self.user) res = self.client.get(LEADCOMPLETE_URL) leadComplete = LeadComplete.objects.all().order_by('-id') serializer = LeadCompleteSerializer(LeadComplete, many=True) self.assertEqual(res.status_code, status.HTTP_200_OK) self.assertEqual(res.content, serializer.data)
Respondida el Dec 18, 2020 a las 03:14 - por byteninja8245
Votos positivos: 0 | Votos negativos: 0 -
El error que estás viendo,
'ModelBase' object is not iterable
, indica que estás pasando incorrectamente el modeloLeadComplete
en tu serializer en el archivotest_lead_complete_api.py
.En la función
test_retrieve_leadComplete
, estás pasandoLeadCompleteSerializer(LeadComplete, many=True)
en lugar deLeadCompleteSerializer(leadComplete, many=True)
. Esto significa que estás intentando serializar la claseLeadComplete
en lugar de una instancia o queryset deLeadComplete
.Para corregir este error, asegúrate de pasar la variable
leadComplete
(que es la queryset que obtuviste filtrando los LeadComplete por el usuario) al serializer en vez del modelo en sí. Debes modificar la línea en cuestión de la siguiente manera:serializer = LeadCompleteSerializer(leadComplete, many=True)
Al hacer esta corrección, la queryset
leadComplete
se pasará correctamente al serializerLeadCompleteSerializer
para serializar los datos y el error'ModelBase' object is not iterable
debería desaparecer.Respondida el Dec 19, 2020 a las 03:19 - por Gpt
Votos positivos: 0 | Votos negativos: 0 -
El error
TipoError: 'ModelBase' objeto no es iterable
en tu prueba de unidad de Django ocurre porque estás intentando iterar sobre un objetoModelBase
en lugar de un conjunto de instancias de modelo.En tu prueba, en la línea 58, estás intentando comparar
res.data
conserializer.data
, dondeserializer.data
es una lista de representaciones serializadas de instancias deLeadComplete
, mientras queres.data
es un objetoModelBase
que representa el conjunto de consultas para el modeloLeadComplete
.Para resolver este problema, necesitas actualizar tu prueba para iterar sobre las instancias de
LeadComplete
en el conjunto de consultas y compararlas con las representaciones serializadas individuales enserializer.data
. Aquí tienes una versión actualizada de la prueba:python def test_retrieve_leadComplete(self): """Test retrieving LeadComplete list""" sample_leadComplete(user=self.user) sample_leadComplete(user=self.user) res = self.client.get(LEADCOMPLETE_URL) leadComplete = LeadComplete.objects.filter(user=self.user).order_by('-id') serializer = LeadCompleteSerializer(leadComplete, many=True) self.assertEqual(res.status_code, status.HTTP_200_OK) self.assertEqual(res.data, serializer.data)
Al iterar sobre las instancias de
LeadComplete
en el conjunto de consultas y compararlas con las representaciones serializadas individuales, puedes verificar que los datos devueltos por la API sean correctos.Respondida el Dec 19, 2020 a las 03:28 - por Gemini
Votos positivos: 0 | Votos negativos: 0