From 0a89478972867d1d5527bfd41d2919d5e753b02c Mon Sep 17 00:00:00 2001 From: Pierre Dulac Date: Fri, 16 Oct 2015 15:37:26 +0200 Subject: [PATCH] Use compat implementations for the old meta api methods --- rest_framework/compat.py | 24 ++++++++++++++++++++++++ rest_framework/utils/model_meta.py | 23 ++++++----------------- 2 files changed, 30 insertions(+), 17 deletions(-) diff --git a/rest_framework/compat.py b/rest_framework/compat.py index 1ef3e1751..43ee2a1f0 100644 --- a/rest_framework/compat.py +++ b/rest_framework/compat.py @@ -71,6 +71,30 @@ except ImportError: JSONField = None +# Models Options old meta api +# Django 1.8 introduced the `Options.get_fields` method that can be used to +# implement *old* meta api methods +# See: https://docs.djangoproject.com/en/1.9/ref/models/meta/#migrating-from-the-old-api +if django.VERSION >= (1, 8): + def get_all_related_objects(opts): + return [ + f for f in opts.get_fields() + if (f.one_to_many or f.one_to_one) and f.auto_created + ] + + def get_all_related_many_to_many_objects(opts): + return [ + f for f in opts.get_fields(include_hidden=True) + if f.many_to_many and f.auto_created + ] +else: + def get_all_related_objects(opts): + return opts.get_all_related_objects() + + def get_all_related_many_to_many_objects(opts): + return opts.get_all_related_many_to_many_objects() + + # 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 e51b57b37..ae0df2fb6 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_objects, get_all_related_many_to_many_objects +) + FieldInfo = namedtuple('FieldResult', [ 'pk', # Model field instance 'fields', # Dict of field name -> model field instance @@ -126,15 +130,7 @@ def _get_reverse_relationships(opts): # See: https://code.djangoproject.com/ticket/24208 reverse_relations = OrderedDict() - - # The backward implementation can be found in the Django Documentation - # See: https://docs.djangoproject.com/en/1.9/ref/models/meta/#migrating-from-the-old-api - related_objects = [ - f for f in opts.get_fields() - if (f.one_to_many or f.one_to_one) and f.auto_created - ] - - for relation in 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( @@ -144,15 +140,8 @@ def _get_reverse_relationships(opts): has_through_model=False ) - # The backward implementation can be found in the Django Documentation - # See: https://docs.djangoproject.com/en/1.9/ref/models/meta/#migrating-from-the-old-api - all_related_to_many_objects = [ - f for f in opts.get_fields(include_hidden=True) - if f.many_to_many and f.auto_created - ] - # Deal with reverse many-to-many relationships. - for relation in all_related_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(