The error occurs after inserting the DetallePedido record, the serializer is looking for the fields ‘producto’ and ‘cantidad’. And it receives a Producto object and an integer (cantidad) and it is looking for the field ‘producto’ inside the Producto object, that’s why the error occurs. And at the end of the create() function it sends the Pedido object with the empty detalles_pedido attribute which is where the DetallePedido records should be stored. Any idea how to fix it?
error: Got AttributeError when attempting to get a value for field producto
on serializer DetallesPedidoSerializer
.
The serializer field might be named incorrectly and not match any attribute or key on the Producto
instance.
Original exception text was: ‘Producto’ object has no attribute ‘producto’.
models.py
class Producto(models.Model):
nombre = models.CharField(max_length=100, blank=False, default='')
precio = models.DecimalField(max_digits=6, decimal_places=2)
coste_envio = models.DecimalField(max_digits=6, decimal_places=2)
def __str__(self):
return self.nombre
class Pedido(models.Model):
ESTADOS = {
'pendiente': 'Pendiente',
'pagado': 'Pagado',
'enviado': 'Enviado',
'entregado': 'Entregado',
}
cliente = models.ForeignKey(User, on_delete=models.CASCADE)
direccion = models.CharField(max_length=300)
fecha_creacion = models.DateTimeField(auto_now_add=True)
estado = models.CharField(max_length=10, choices=ESTADOS, default=ESTADOS['pendiente'])
detalles_pedido = models.ManyToManyField(Producto, through='DetallePedido')
def save(self, *args, **kwargs):
super().save(*args, **kwargs)
def __str__(self):
return f'Pedido {self.id} - {self.cliente}'
class DetallePedido(models.Model):
pedido = models.ForeignKey(Pedido, on_delete=models.CASCADE)
producto = models.ForeignKey(Producto, on_delete=models.CASCADE)
cantidad = models.PositiveIntegerField()
def __str__(self):
return f'{self.producto.id} - {self.cantidad} - {self.pedido.cliente}'`
serializers.py
class ProductoSerializer(serializers.ModelSerializer):
class Meta:
model = Producto
fields = ['id', 'nombre', 'precio', 'coste_envio']
class DetallesPedidoSerializer(serializers.ModelSerializer):
producto = serializers.PrimaryKeyRelatedField(queryset=Producto.objects.all())
class Meta:
model = DetallePedido
fields = ['producto', 'cantidad']
class PedidoSerializer(serializers.ModelSerializer):
detalles_pedido = DetallesPedidoSerializer(many=True)
class Meta:
model = Pedido
fields = ['cliente', 'direccion', 'estado', 'detalles_pedido']
extra_kwargs = {
'cliente': {'required': False}
}
def create(self, validated_data):
productos_data = validated_data.pop('detalles_pedido')
pedido = Pedido.objects.create(**validated_data)
for producto_data in productos_data:
detalle = DetallePedido.objects.create(pedido=pedido,
producto=producto_data['producto'],
cantidad=producto_data['cantidad']
)
# Here i can print detalle object and is inserted in db
return pedido
views.py
@api_view(['POST'])
@permission_classes([IsAuthenticated,])
def pedido_create(request):
if request.method == 'POST':
data = request.data.copy()
data['cliente'] = request.user.id
serializer = serializers.PedidoSerializer(data=data)
if serializer.is_valid():
serializer.save()
return Response(serializer.data, status=status.HTTP_201_CREATED)
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
error: Got AttributeError when attempting to get a value for field producto
on serializer DetallesPedidoSerializer
.
The serializer field might be named incorrectly and not match any attribute or key on the Producto
instance.
Original exception text was: ‘Producto’ object has no attribute ‘producto’.
user26392447 is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.
1
You can specify the source as:
class PedidoSerializer(serializers.ModelSerializer):
detalles_pedido = DetallesPedidoSerializer(
many=True, source='detallespedido_set'
)
# …
This is the default of the related_name
of the query in reverse.