Repository: encode/django-rest-framework

Issue:
Validation error on raise_errors_on_nested_writes?
I have problems with nested serializers, the idea is to read with nested serializer and write with a primaryKeyRelated, but I have a nested write alert with my example:
### Raise error

```
class WorkerSerializer(serializers.ModelSerializer):
    roles = data_serializers.RoleSerializer(many=True, read_only=True)
    roles_ids = serializers.PrimaryKeyRelatedField(
        allow_empty=False, many=True, queryset=data_models.Role.objects.all(),
        write_only=True, source="roles"
    )
```
### This works

```
class WorkerSerializer(serializers.ModelSerializer):
    roles_data = data_serializers.RoleSerializer(many=True, read_only=True, source="roles")
    roles = serializers.PrimaryKeyRelatedField(
        allow_empty=False, many=True, queryset=data_models.Role.objects.all(),
        write_only=True
    )
```

This doesn't look a big problem, but for me it's huge to change a big api implementation, this behavior repeats a lot and I believe the solution it's quite simple.

I find in raise_errors_on_nested_writes function this validation:

```
    assert not any(
        isinstance(field, BaseSerializer) and
        (key in validated_data) and
        isinstance(validated_data[key], (list, dict))
        for key, field in serializer.fields.items()
    ), (
        'The `.{method_name}()` method does not support writable nested '
        'fields by default.\nWrite an explicit `.{method_name}()` method for '
        'serializer `{module}.{class_name}`, or set `read_only=True` on '
        'nested serializer fields.'.format(
            method_name=method_name,
            module=serializer.__class__.__module__,
            class_name=serializer.__class__.__name__
        )
    )
```

Adding a read_only check fix my problem

```
    assert not any(
        not field.read_only and
        isinstance(field, BaseSerializer) and
        (key in validated_data) and
        isinstance(validated_data[key], (list, dict))
        for key, field in serializer.fields.items()
    ), (
        'The `.{method_name}()` method does not support writable nested '
        'fields by default.\nWrite an explicit `.{method_name}()` method for '
        'serializer `{module}.{class_name}`, or set `read_only=True` on '
        'nested serializer fields.'.format(
            method_name=method_name,
            module=serializer.__class__.__module__,
            class_name=serializer.__class__.__name__
        )
    )
```

My first issue on github, so I hope it's ok.
Thanks



Discussion:
Seems fair - bit of an odd edge case the way it's been used, but yup see the issue.
Might be that we want to do something along the lines of testing `field.source` instead of `key` in `validated_data`, wasn't expecting to have to test `read_only` as we _already_ check if the data exists or not.

Started to look into resolving this, but trying to create the test case started taking slightly longer than expected.

If anyone is able to submit a failing test case, or provide the _simplest possible_ example of how to replicate this would go a long way towards helping get this case resolved.


Resolving patch:
diff --git a/rest_framework/serializers.py b/rest_framework/serializers.py
--- a/rest_framework/serializers.py
+++ b/rest_framework/serializers.py
@@ -744,8 +744,8 @@ def raise_errors_on_nested_writes(method_name, serializer, validated_data):
     #     profile = ProfileSerializer()
     assert not any(
         isinstance(field, BaseSerializer) and
-        (key in validated_data) and
-        isinstance(validated_data[key], (list, dict))
+        (field.source in validated_data) and
+        isinstance(validated_data[field.source], (list, dict))
         for key, field in serializer.fields.items()
     ), (
         'The `.{method_name}()` method does not support writable nested '


Test patch: