tomchristie/django-rest-framework — pull request #1170 by craigds (2013-10-11 02:49:11+00:00)
Title: fix writing into foreign key with non-null source

We have this field:

class SourceUpdateSerializer(serializers.ModelSerializer):
options = UrlOptionsSerializer(source='connection_info', required=False)

I try to write into it:

PUT /sources/123/
{
"options": {"ssl_verify": true}
}

Big ugly traceback:

Traceback:
File "/home/cdestigter/checkout/django/django/core/handlers/base.py" in get_response
115. response = callback(request, *callback_args, **callback_kwargs)
File "/home/cdestigter/checkout/django-rest-framework/rest_framework/viewsets.py" in view
78. return self.dispatch(request, *args, **kwargs)
File "/home/cdestigter/checkout/django/django/views/decorators/csrf.py" in wrapped_view
77. return view_func(*args, **kwargs)
File "/home/cdestigter/checkout/django-rest-framework/rest_framework/views.py" in dispatch
399. response = self.handle_exception(exc)
File "/home/cdestigter/checkout/django-rest-framework/rest_framework/views.py" in dispatch
396. response = handler(request, *args, **kwargs)
File "/usr/local/lib/python2.6/dist-packages/poppy/utils/viewsets.py" in update
164. serializer = self.apply_update(request, pk)
File "/usr/local/lib/python2.6/dist-packages/poppy/utils/viewsets.py" in apply_update
155. if serializer.is_valid():
File "/home/cdestigter/checkout/django-rest-framework/rest_framework/serializers.py" in is_valid
506. return not self.errors
File "/home/cdestigter/checkout/django-rest-framework/rest_framework/serializers.py" in errors
498. ret = self.from_native(data, files)
File "/usr/local/lib/python2.6/dist-packages/poppy/utils/serializers.py" in from_native
473. ret = subserializer.from_native(data, files)
File "/usr/local/lib/python2.6/dist-packages/poppy/utils/serializers.py" in from_native
450. return super(TypeableSerializer, self).from_native(data, files)
File "/home/cdestigter/checkout/django-rest-framework/rest_framework/serializers.py" in from_native
909. instance = super(ModelSerializer, self).from_native(data, files)
File "/home/cdestigter/checkout/django-rest-framework/rest_framework/serializers.py" in from_native
341. attrs = self.restore_fields(data, files)
File "/usr/local/lib/python2.6/dist-packages/poppy/sources/serializers/base.py" in restore_fields
203. attrs = super(SourceBaseSerializer, self).restore_fields(data, files)
File "/home/cdestigter/checkout/django-rest-framework/rest_framework/serializers.py" in restore_fields
263. field.field_from_native(data, files, field_name, reverted_data)
File "/home/cdestigter/checkout/django-rest-framework/rest_framework/serializers.py" in field_from_native
405. obj = getattr(self.parent.object, field_name) if self.parent.object else None

Exception Type: AttributeError at /services/api/v1/sources/1404/
Exception Value: 'WfsSource' object has no attribute 'options'

The problem is that the writable serializer code ignores `self.source` when updating an existing model rather than creating a new one. This PR fixes the issue and includes tests.