diff --git a/rest_framework/relations.py b/rest_framework/relations.py index 1d20ee82b..29585a816 100644 --- a/rest_framework/relations.py +++ b/rest_framework/relations.py @@ -109,6 +109,8 @@ class RelatedField(Field): try: instance = get_attribute(instance, self.source_attrs[:-1]) + # Handle edge case where the relationship `source` argument + # points to a `get_relationship()` method on the model value = instance.serializable_value(self.source_attrs[-1]) if is_simple_callable(value): value = value().pk diff --git a/tests/models.py b/tests/models.py index 4537ae33e..c265182b7 100644 --- a/tests/models.py +++ b/tests/models.py @@ -15,10 +15,7 @@ class RESTFrameworkModel(models.Model): class BasicModel(RESTFrameworkModel): - text = models.CharField( - max_length=100, - verbose_name=_("Text comes here"), - help_text=_("Text description.")) + text = models.CharField(max_length=100, verbose_name=_("Text comes here"), help_text=_("Text description.")) class BaseFilterableItem(RESTFrameworkModel): @@ -48,12 +45,6 @@ class ManyToManySource(RESTFrameworkModel): class ForeignKeyTarget(RESTFrameworkModel): name = models.CharField(max_length=100) - def get_first_source(self): - try: - return self.sources.all()[0] - except IndexError: - return None - class ForeignKeySource(RESTFrameworkModel): name = models.CharField(max_length=100) diff --git a/tests/test_relations_hyperlink.py b/tests/test_relations_hyperlink.py index cadef5fff..c0642eda2 100644 --- a/tests/test_relations_hyperlink.py +++ b/tests/test_relations_hyperlink.py @@ -50,17 +50,6 @@ class ForeignKeyTargetSerializer(serializers.HyperlinkedModelSerializer): fields = ('url', 'name', 'sources') -class ForeignKeyTargetCallableSourceSerializer(serializers.HyperlinkedModelSerializer): - class Meta: - model = ForeignKeyTarget - fields = ('url', 'name', 'first_source') - - first_source = serializers.HyperlinkedRelatedField( - read_only=True, - source='get_first_source', - view_name='foreignkeysource-detail') - - class ForeignKeySourceSerializer(serializers.HyperlinkedModelSerializer): class Meta: model = ForeignKeySource @@ -455,22 +444,3 @@ class HyperlinkedNullableOneToOneTests(TestCase): {'url': 'http://testserver/onetoonetarget/2/', 'name': 'target-2', 'nullable_source': None}, ] self.assertEqual(serializer.data, expected) - - -class HyperlinkedRelationCallableSourceTests(TestCase): - urls = 'tests.test_relations_hyperlink' - - def setUp(self): - self.target = ForeignKeyTarget.objects.create(name='target-1') - ForeignKeySource.objects.create(name='source-1', target=self.target) - ForeignKeySource.objects.create(name='source-2', target=self.target) - - def test_relation_field_callable_source(self): - serializer = ForeignKeyTargetCallableSourceSerializer(self.target, context={'request': request}) - expected = { - 'url': 'http://testserver/foreignkeytarget/1/', - 'name': 'target-1', - 'first_source': 'http://testserver/foreignkeysource/1/', - } - with self.assertNumQueries(1): - self.assertEqual(serializer.data, expected) diff --git a/tests/test_relations_pk.py b/tests/test_relations_pk.py index 505d4d959..169f7d9c5 100644 --- a/tests/test_relations_pk.py +++ b/tests/test_relations_pk.py @@ -30,16 +30,6 @@ class ForeignKeyTargetSerializer(serializers.ModelSerializer): fields = ('id', 'name', 'sources') -class ForeignKeyTargetCallableSourceSerializer(serializers.ModelSerializer): - class Meta: - model = ForeignKeyTarget - fields = ('id', 'name', 'first_source') - - first_source = serializers.PrimaryKeyRelatedField( - read_only=True, - source='get_first_source') - - class ForeignKeySourceSerializer(serializers.ModelSerializer): class Meta: model = ForeignKeySource @@ -460,21 +450,3 @@ class PKNullableOneToOneTests(TestCase): {'id': 2, 'name': 'target-2', 'nullable_source': 1}, ] self.assertEqual(serializer.data, expected) - - -class PKRelationCallableSourceTests(TestCase): - - def setUp(self): - self.target = ForeignKeyTarget.objects.create(name='target-1') - self.first_source = ForeignKeySource.objects.create(id=10, name='source-1', target=self.target) - ForeignKeySource.objects.create(name='source-2', target=self.target) - - def test_relation_field_callable_source(self): - serializer = ForeignKeyTargetCallableSourceSerializer(self.target) - expected = { - 'id': 1, - 'name': 'target-1', - 'first_source': 10, - } - with self.assertNumQueries(1): - self.assertEqual(serializer.data, expected)