Skip to content

Not able to deserialize OneToOneField relationships in DRF>=3.7.0 #27

@c-oreills

Description

@c-oreills

Hi Ian,

I've run into an issue when upgrading DRF to v3.7.7 due to our use of expandable_fields

If I have the following code:

class Parent(models.Model):
    pass

class Child(models.Model):
    parent = models.OneToOneField(Parent)

class ChildSerializer(SerializerExtensionsMixin, ModelSerializer):
    class Meta:
        model = Child
        fields = ('id',)

class ParentSerializer(SerializerExtensionsMixin, ModelSerializer):
    class Meta:
        model = Parent
        fields = ('id',)
        expandable_fields = dict(
            child=dict(
                serializer=ChildSerializer,
                id_source='child.id'
            ))

Then this test will fail:

class TestModels(TestCase):
    def test(self):
        parent = Parent.objects.create()

        ParentSerializer(parent).data

with:

Traceback (most recent call last):
  File "/home/christy/projects/dsetest/dseapp/tests.py", line 13, in test
    ParentSerializer(parent).data
  File "/home/christy/.virtualenvs/dsetest/local/lib/python2.7/site-packages/rest_framework/serializers.py", line 537, in data
    ret = super(Serializer, self).data
  File "/home/christy/.virtualenvs/dsetest/local/lib/python2.7/site-packages/rest_framework/serializers.py", line 262, in data
    self._data = self.to_representation(self.instance)
  File "/home/christy/.virtualenvs/dsetest/local/lib/python2.7/site-packages/rest_framework/serializers.py", line 491, in to_representation
    attribute = field.get_attribute(instance)
  File "/home/christy/.virtualenvs/dsetest/local/lib/python2.7/site-packages/rest_framework/relations.py", line 177, in get_attribute
    return get_attribute(instance, self.source_attrs)
  File "/home/christy/.virtualenvs/dsetest/local/lib/python2.7/site-packages/rest_framework/fields.py", line 100, in get_attribute
    instance = getattr(instance, attr)
AttributeError: 'NoneType' object has no attribute 'child'

If I create a Child model and link it to parent, the test passes.

Note that this works in DRF<=3.6.4

I believe this to be due to this commit, which has been linked to this issue and this PR.

We can work around this at other points in our codebase by specifying default=None in serializer fields, however this isn't supported in serializer extensions.

I've created a repo with a POC here (requirements file has necessary library versions).

I'd appreciate any input on how this could be resolved - one option would be remove from expandable_fields and make this a first class field on the serializer but that would require finding all clients which request the expandable field and changing them to no longer ask for it.

Thanks very much in advance!

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions