The `.create()` method does not support writable nested fields by default.

DRF does not support create method for nested serializers. If you want to show related fields in an extended layout and not only with pks then you can override the to_representation method instead of rewriting default mtm field. You should also override a create method, because of the third model in mtm link:

class EquipmentSerializer(serializers.ModelSerializer): 

    class Meta: 
        model = Equipment 
        fields = '__all__'

    def create(self, validated_data):
        order = Order.objects.get(pk=validated_data.pop('event'))
        instance = Equipment.objects.create(**validated_data)
        Assignment.objects.create(Order=order, Equipment=instance)
        return instance

    def to_representation(self, instance):
        representation = super(EquipmentSerializer, self).to_representation(instance)
        representation['assigment'] = AssignmentSerializer(instance.assigment_set.all(), many=True).data
        return representation 

Now it'll save mtm fields properly passing list of pks, like [1, 2, 3] and for representation of that mtm related model, EquipmentSerializer will use AssignmentSerializer.


Maybe for most people who is having the same issue, this question is a quite long.

The short answer is that DRF does not support natively create method for nested serializers. so what to do?

Simply overriding the default behaviour. Check out a full example in the Official DRF docs


I had a similar problem but with the update() method ...

The solution was simple thanks to this thread: https://github.com/beda-software/drf-writable-nested/issues/104...

All I had to do was installing the library pip install drf-writable-nested and import it:

from drf_writable_nested import WritableNestedModelSerializer

the code should look like this:

(credit to: https://github.com/Leonardoperrella)

--serializers.py--

from drf_writable_nested import WritableNestedModelSerializer

class ProductsSerializer(serializers.ModelSerializer):
    class Meta:
        model = Products
        fields = ('name', 'code', 'price')

class VendorsSerializer(WritableNestedModelSerializer,
                        serializers.ModelSerializer):
    products = ProductsSerializer(source='vendor', many=True)
    class Meta:
        model = Vendors
        fields = ('name', 'cnpj', 'city', 'products')

--models.py--

class Vendors(models.Model):
    name = models.CharField('Name', max_length=50)
    cnpj = models.CharField('CNPJ', max_length=14, unique=True, validators=[validate_cnpj])
    city = models.CharField('City', max_length=100, blank=True)

    class Meta:
        verbose_name = "Vendor"
        verbose_name_plural = "Vendors"

    def __str__(self):
        return self.name


class Products(models.Model):
    name = models.CharField('Name', max_length=60)
    code = models.CharField('Code', max_length=13)
    price = models.DecimalField('Price',
                                max_digits=15,
                                decimal_places=2,
                                default=0.00,
                                validators=[MinValueValidator(Decimal("0.01"))])
    vendor = models.ForeignKey('Vendors', on_delete=models.CASCADE, related_name='vendor')

    class Meta:
        verbose_name = "Product"
        verbose_name_plural = "Products"

    def __str__(self):
        return self.name