Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 23 additions & 3 deletions rest_framework/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -1157,9 +1157,29 @@ def build_relational_field(self, field_name, relation_info):
field_kwargs = get_relation_kwargs(field_name, relation_info)

to_field = field_kwargs.pop('to_field', None)
if to_field and not relation_info.related_model._meta.get_field(to_field).primary_key:
field_kwargs['slug_field'] = to_field
field_class = self.serializer_related_to_field
if to_field:
def get_related_field(related_model, to_field):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Haven't looked into the issue in any depth, but we'd certainly want to factor this out. Eg have it as a function somewhere in rest_framework.utils

'''Returns the primary key of the field defined by to_field
on the model passed in'''
from django.core.exceptions import FieldDoesNotExist
try:
return related_model._meta.get_field(to_field)
except FieldDoesNotExist:
for field in related_model._meta.fields:
if field.related_model:
try:
new_field = get_related_field(
field.related_model, to_field)
return new_field
except FieldDoesNotExist:
continue
raise FieldDoesNotExist(
'%s has not field named %r' % (related_model, to_field))
pk = (get_related_field(relation_info.related_model, to_field)
.primary_key)
if not pk:
field_kwargs['slug_field'] = to_field
field_class = self.serializer_related_to_field

# `view_name` is only valid for hyperlinked relationships.
if not issubclass(field_class, HyperlinkedRelatedField):
Expand Down
44 changes: 44 additions & 0 deletions tests/test_onetoone_with_inheritance.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
from __future__ import unicode_literals

from django.db import models
from django.test import TestCase

from rest_framework import serializers
from tests.models import RESTFrameworkModel


# Models
from tests.test_multitable_inheritance import ChildModel


class ChildAssociatedModel(RESTFrameworkModel):
child_model = models.OneToOneField(ChildModel)
child_name = models.CharField(max_length=100)


# Serializers
class DerivedModelSerializer(serializers.ModelSerializer):
class Meta:
model = ChildModel
fields = ['id', 'name1', 'name2', 'childassociatedmodel']


class ChildAssociatedModelSerializer(serializers.ModelSerializer):

class Meta:
model = ChildAssociatedModel
fields = ['id', 'child_name']


# Tests
class InheritedModelSerializationTests(TestCase):

def test_multitable_inherited_model_fields_as_expected(self):
"""
Assert that the parent pointer field is not included in the fields
serialized fields
"""
child = ChildModel(name1='parent name', name2='child name')
serializer = DerivedModelSerializer(child)
self.assertEqual(set(serializer.data.keys()),
set(['name1', 'name2', 'id', 'childassociatedmodel']))