From a85d546d7659f37a799ded686fb8543dc2dddec2 Mon Sep 17 00:00:00 2001 From: Raphael Date: Tue, 30 May 2017 11:33:32 +0200 Subject: [PATCH 1/4] Adds test that fails with reverse m2m relationships --- example/models.py | 2 +- example/serializers.py | 4 ++-- example/tests/test_utils.py | 11 ++++++++++- 3 files changed, 13 insertions(+), 4 deletions(-) diff --git a/example/models.py b/example/models.py index 6442b0e4..68b0e57b 100644 --- a/example/models.py +++ b/example/models.py @@ -64,7 +64,7 @@ class Entry(BaseModel): body_text = models.TextField(null=True) pub_date = models.DateField(null=True) mod_date = models.DateField(null=True) - authors = models.ManyToManyField(Author) + authors = models.ManyToManyField(Author, related_name='entries') n_comments = models.IntegerField(default=0) n_pingbacks = models.IntegerField(default=0) rating = models.IntegerField(default=0) diff --git a/example/serializers.py b/example/serializers.py index 0dfc49b4..37d76803 100644 --- a/example/serializers.py +++ b/example/serializers.py @@ -92,7 +92,7 @@ class AuthorBioSerializer(serializers.ModelSerializer): class Meta: model = AuthorBio - fields = ('author', 'body',) + fields = ('author', 'body') class AuthorSerializer(serializers.ModelSerializer): @@ -102,7 +102,7 @@ class AuthorSerializer(serializers.ModelSerializer): class Meta: model = Author - fields = ('name', 'email', 'bio') + fields = ('name', 'email', 'bio', 'entries') class CommentSerializer(serializers.ModelSerializer): diff --git a/example/tests/test_utils.py b/example/tests/test_utils.py index 3772ebe1..d431db12 100644 --- a/example/tests/test_utils.py +++ b/example/tests/test_utils.py @@ -3,7 +3,7 @@ """ from rest_framework_json_api import utils -from ..serializers import EntrySerializer +from ..serializers import EntrySerializer, AuthorSerializer from ..tests import TestBase @@ -29,3 +29,12 @@ def test_m2m_relation(self): field = serializer.fields['authors'] self.assertEqual(utils.get_related_resource_type(field), 'authors') + + def test_m2m_reverse_relation(self): + """ + Ensure reverse m2ms have their types identified correctly. + """ + serializer = AuthorSerializer() + field = serializer.fields['entries'] + + self.assertEqual(utils.get_related_resource_type(field), 'entries') From 916d45fc66dcb0144335ec15fdd56677a4486900 Mon Sep 17 00:00:00 2001 From: Raphael Date: Tue, 30 May 2017 11:33:54 +0200 Subject: [PATCH 2/4] Fixes reverse m2m relationships --- rest_framework_json_api/utils.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/rest_framework_json_api/utils.py b/rest_framework_json_api/utils.py index f2eefa2b..b9037b4a 100644 --- a/rest_framework_json_api/utils.py +++ b/rest_framework_json_api/utils.py @@ -238,6 +238,9 @@ def get_related_resource_type(relation): relation_model = parent_model_relation.related.model elif parent_model_relation_type is ManyToManyDescriptor: relation_model = parent_model_relation.field.remote_field.model + # In case we are in a reverse relation case + if relation_model == parent_model: + relation_model = parent_model_relation.field.model elif parent_model_relation_type is ReverseManyRelatedObjectsDescriptor: relation_model = parent_model_relation.field.related.model elif parent_model_relation_type is ReverseGenericManyToOneDescriptor: From d6810a878022b90000ba73737928aa506b7c90bb Mon Sep 17 00:00:00 2001 From: Raphael Date: Tue, 30 May 2017 12:04:09 +0200 Subject: [PATCH 3/4] Adds compatibility with Django 1.8 --- rest_framework_json_api/utils.py | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/rest_framework_json_api/utils.py b/rest_framework_json_api/utils.py index b9037b4a..85d70c0a 100644 --- a/rest_framework_json_api/utils.py +++ b/rest_framework_json_api/utils.py @@ -237,10 +237,16 @@ def get_related_resource_type(relation): else: relation_model = parent_model_relation.related.model elif parent_model_relation_type is ManyToManyDescriptor: - relation_model = parent_model_relation.field.remote_field.model - # In case we are in a reverse relation case - if relation_model == parent_model: - relation_model = parent_model_relation.field.model + if django.VERSION >= (1, 9): + relation_model = parent_model_relation.field.remote_field.model + # In case we are in a reverse relation + if relation_model == parent_model: + relation_model = parent_model_relation.field.model + elif django.VERSION >= (1, 8): + relation_model = parent_model_relation.related.model + # In case we are in a reverse relation + if relation_model == parent_model: + relation_model = parent_model_relation.related.related_model elif parent_model_relation_type is ReverseManyRelatedObjectsDescriptor: relation_model = parent_model_relation.field.related.model elif parent_model_relation_type is ReverseGenericManyToOneDescriptor: From cce737ed976275334eae56c8397038914326be48 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rapha=C3=ABl=20Cohen?= Date: Thu, 1 Jun 2017 17:12:28 +0200 Subject: [PATCH 4/4] Update AUTHORS --- AUTHORS | 1 + 1 file changed, 1 insertion(+) diff --git a/AUTHORS b/AUTHORS index 419f2e90..040fb7d9 100644 --- a/AUTHORS +++ b/AUTHORS @@ -4,4 +4,5 @@ Greg Aker Jerel Unruh Matt Layman Oliver Sauder +Raphael Cohen Yaniv Peer