Repository: encode/django-rest-framework

Issue:
Model._meta API warnings with Django 1.9 (RemovedInDjango110Warning)
Whilst running Django 1.9.dev (master) I'm getting a couple of warnings in relations to the changes in the [Model._meta API](https://docs.djangoproject.com/en/1.8/ref/models/meta/) introduced in Django 1.8.

> .../lib/python3.4/site-packages/rest_framework/utils/model_meta.py:130: RemovedInDjango110Warning: 'get_all_related_objects is an unofficial API that has been deprecated. You may be able to replace it with 'get_fields()'
>   for relation in opts.get_all_related_objects():
> 
> .../lib/python3.4/site-packages/rest_framework/utils/model_meta.py:141: RemovedInDjango110Warning: 'get_all_related_many_to_many_objects is an unofficial API that has been deprecated. You may be able to replace it with 'get_fields()'
>   for relation in opts.get_all_related_many_to_many_objects():



Discussion:
Noted, thanks.
We'll aim to clear this up as part of official 1.9 support when that comes out.

Now resolved in master.

Now running Django 1.9b1 and DRF 3.3.0 I'm continuing to get a couple of warnings in relations to the changes in the [Model._meta API](https://docs.djangoproject.com/en/1.8/ref/models/meta/) introduced in Django 1.8.

> ...lib/python3.4/site-packages/rest_framework/utils/model_meta.py:137: RemovedInDjango110Warning: 'get_all_related_objects is an unofficial API that has been deprecated. You may be able to replace it with 'get_fields()'
>   for relation in opts.get_all_related_objects():
> 
> .../lib/python3.4/site-packages/rest_framework/utils/model_meta.py:149: RemovedInDjango110Warning: 'get_all_related_many_to_many_objects is an unofficial API that has been deprecated. You may be able to replace it with 'get_fields()'
>   for relation in opts.get_all_related_many_to_many_objects():

Thanks for the report.


Resolving patch:
diff --git a/rest_framework/compat.py b/rest_framework/compat.py
--- 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
--- 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(


Test patch: