From f172f0d43f49001698de0fb0bb3a7a0cd750bee0 Mon Sep 17 00:00:00 2001 From: Pierre Dulac Date: Fri, 16 Oct 2015 16:21:59 +0200 Subject: [PATCH] Fix the compatibility with the OneToOneField class --- rest_framework/compat.py | 15 +++++++++++++++ rest_framework/utils/model_meta.py | 17 +++++++++++------ 2 files changed, 26 insertions(+), 6 deletions(-) diff --git a/rest_framework/compat.py b/rest_framework/compat.py index 43ee2a1f0..178339a36 100644 --- a/rest_framework/compat.py +++ b/rest_framework/compat.py @@ -95,6 +95,21 @@ else: return opts.get_all_related_many_to_many_objects() +# Compatibility for the *field* instance returned by either +# the old `Options.get_all_related_objects` or our own implementation above +def get_relation_accessor_name(relation): + if not hasattr(relation, 'get_accessor_name'): + # special case for the `OneToOneField` instances + return relation.name + return relation.get_accessor_name() + +def get_relation_field(relation): + if not hasattr(relation, 'get_accessor_name'): + # special case for the `OneToOneField` instances + return relation + return relation.field + + # django-filter is optional try: import django_filters diff --git a/rest_framework/utils/model_meta.py b/rest_framework/utils/model_meta.py index ae0df2fb6..ae770392a 100644 --- a/rest_framework/utils/model_meta.py +++ b/rest_framework/utils/model_meta.py @@ -14,7 +14,10 @@ from django.db import models from django.utils import six from rest_framework.compat import ( - get_all_related_objects, get_all_related_many_to_many_objects + get_all_related_objects, + get_all_related_many_to_many_objects, + get_relation_accessor_name, + get_relation_field ) FieldInfo = namedtuple('FieldResult', [ @@ -131,26 +134,28 @@ def _get_reverse_relationships(opts): reverse_relations = OrderedDict() for relation in get_all_related_objects(opts): - accessor_name = relation.get_accessor_name() + accessor_name = get_relation_accessor_name(relation) + field = get_relation_field(relation) related = getattr(relation, 'related_model', relation.model) reverse_relations[accessor_name] = RelationInfo( model_field=None, related_model=related, - to_many=relation.field.rel.multiple, + to_many=field.rel.multiple, has_through_model=False ) # Deal with reverse many-to-many relationships. for relation in get_all_related_many_to_many_objects(opts): - accessor_name = relation.get_accessor_name() + accessor_name = get_relation_accessor_name(relation) + field = get_relation_field(relation) related = getattr(relation, 'related_model', relation.model) reverse_relations[accessor_name] = RelationInfo( model_field=None, related_model=related, to_many=True, has_through_model=( - (getattr(relation.field.rel, 'through', None) is not None) and - not relation.field.rel.through._meta.auto_created + (getattr(field.rel, 'through', None) is not None) and + not field.rel.through._meta.auto_created ) )