From 2acc6a756cddf9db2ba5d8007b9e9871541fa63c Mon Sep 17 00:00:00 2001 From: Andrei Fokau Date: Wed, 18 Nov 2015 20:17:17 +0100 Subject: [PATCH] Use related_objects api for Django 1.9+ --- rest_framework/compat.py | 29 +++++++++++++++++++++++++++++ rest_framework/utils/model_meta.py | 8 ++++++-- 2 files changed, 35 insertions(+), 2 deletions(-) diff --git a/rest_framework/compat.py b/rest_framework/compat.py index c6966a980..56d006efb 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 77952fbf8..f151c6f36 100644 --- a/rest_framework/utils/model_meta.py +++ b/rest_framework/utils/model_meta.py @@ -13,6 +13,10 @@ from django.core.exceptions import ImproperlyConfigured 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(