diff --git a/rest_framework/compat.py b/rest_framework/compat.py index c6966a980f..56d006efb6 100644 --- a/rest_framework/compat.py +++ b/rest_framework/compat.py @@ -230,3 +230,32 @@ def template_render(template, context=None, request=None): # backends template, e.g. django.template.backends.django.Template else: return template.render(context, request=request) + + +def get_all_related_objects(opts): + """ + Django 1.8 changed meta api, see + https://docs.djangoproject.com/en/1.8/ref/models/meta/#migrating-old-meta-api + https://code.djangoproject.com/ticket/12663 + https://github.com/django/django/pull/3848 + + :param opts: Options instance + :return: list of relations except many-to-many ones + """ + if django.VERSION < (1, 9): + return opts.get_all_related_objects() + else: + return [r for r in opts.related_objects if not r.field.many_to_many] + + +def get_all_related_many_to_many_objects(opts): + """ + Django 1.8 changed meta api, see docstr in compat.get_all_related_objects() + + :param opts: Options instance + :return: list of many-to-many relations + """ + if django.VERSION < (1, 9): + return opts.get_all_related_many_to_many_objects() + else: + return [r for r in opts.related_objects if r.field.many_to_many] diff --git a/rest_framework/utils/model_meta.py b/rest_framework/utils/model_meta.py index 77952fbf89..f151c6f36e 100644 --- a/rest_framework/utils/model_meta.py +++ b/rest_framework/utils/model_meta.py @@ -13,6 +13,10 @@ from django.db import models from django.utils import six +from rest_framework.compat import ( + get_all_related_many_to_many_objects, get_all_related_objects +) + FieldInfo = namedtuple('FieldResult', [ 'pk', # Model field instance 'fields', # Dict of field name -> model field instance @@ -134,7 +138,7 @@ def _get_reverse_relationships(opts): # See: https://code.djangoproject.com/ticket/24208 reverse_relations = OrderedDict() - for relation in opts.get_all_related_objects(): + for relation in get_all_related_objects(opts): accessor_name = relation.get_accessor_name() related = getattr(relation, 'related_model', relation.model) reverse_relations[accessor_name] = RelationInfo( @@ -146,7 +150,7 @@ def _get_reverse_relationships(opts): ) # Deal with reverse many-to-many relationships. - for relation in opts.get_all_related_many_to_many_objects(): + for relation in get_all_related_many_to_many_objects(opts): accessor_name = relation.get_accessor_name() related = getattr(relation, 'related_model', relation.model) reverse_relations[accessor_name] = RelationInfo(