From 004408a9e8621cfb283ada0d5d533a11c34a00d7 Mon Sep 17 00:00:00 2001 From: Justin Plock Date: Fri, 5 Feb 2016 14:17:07 -0500 Subject: [PATCH 1/3] Attempt to address Django 1.9 deprecate warnings related to field.rel --- rest_framework/utils/model_meta.py | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/rest_framework/utils/model_meta.py b/rest_framework/utils/model_meta.py index f151c6f36e..253cd5bcc6 100644 --- a/rest_framework/utils/model_meta.py +++ b/rest_framework/utils/model_meta.py @@ -80,16 +80,16 @@ def get_field_info(model): def _get_pk(opts): pk = opts.pk - while pk.rel and pk.rel.parent_link: + while pk.remote_field and pk.remote_field.parent_link: # If model is a child via multi-table inheritance, use parent's pk. - pk = pk.rel.to._meta.pk + pk = pk.remote_field.to._meta.pk return pk def _get_fields(opts): fields = OrderedDict() - for field in [field for field in opts.fields if field.serialize and not field.rel]: + for field in [field for field in opts.fields if field.serialize and not field.remote_field]: fields[field.name] = field return fields @@ -104,10 +104,10 @@ def _get_forward_relationships(opts): Returns an `OrderedDict` of field names to `RelationInfo`. """ forward_relations = OrderedDict() - for field in [field for field in opts.fields if field.serialize and field.rel]: + for field in [field for field in opts.fields if field.serialize and field.remote_field]: forward_relations[field.name] = RelationInfo( model_field=field, - related_model=_resolve_model(field.rel.to), + related_model=_resolve_model(field.remote_field.to), to_many=False, to_field=_get_to_field(field), has_through_model=False @@ -117,12 +117,12 @@ def _get_forward_relationships(opts): for field in [field for field in opts.many_to_many if field.serialize]: forward_relations[field.name] = RelationInfo( model_field=field, - related_model=_resolve_model(field.rel.to), + related_model=_resolve_model(field.remote_field.to), to_many=True, # manytomany do not have to_fields to_field=None, has_through_model=( - not field.rel.through._meta.auto_created + not field.remote_field.through._meta.auto_created ) ) @@ -144,7 +144,7 @@ def _get_reverse_relationships(opts): reverse_relations[accessor_name] = RelationInfo( model_field=None, related_model=related, - to_many=relation.field.rel.multiple, + to_many=relation.field.remote_field.multiple, to_field=_get_to_field(relation.field), has_through_model=False ) @@ -160,8 +160,8 @@ def _get_reverse_relationships(opts): # manytomany do not have to_fields to_field=None, has_through_model=( - (getattr(relation.field.rel, 'through', None) is not None) and - not relation.field.rel.through._meta.auto_created + (getattr(relation.field.remote_field, 'through', None) is not None) and + not relation.field.remote_field.through._meta.auto_created ) ) From 83e73cd5bb6d0518880d92677c7e0a44918d5a51 Mon Sep 17 00:00:00 2001 From: Justin Plock Date: Sat, 6 Feb 2016 09:02:01 -0500 Subject: [PATCH 2/3] Added a compatibility function to support versions prior to Django 1.9 --- rest_framework/compat.py | 13 +++++++++++++ rest_framework/utils/model_meta.py | 23 ++++++++++++----------- 2 files changed, 25 insertions(+), 11 deletions(-) diff --git a/rest_framework/compat.py b/rest_framework/compat.py index adce32be81..20f8bbb37b 100644 --- a/rest_framework/compat.py +++ b/rest_framework/compat.py @@ -268,3 +268,16 @@ def get_all_related_many_to_many_objects(opts): return opts.get_all_related_many_to_many_objects() else: return [r for r in opts.related_objects if r.field.many_to_many] + +def get_remote_field(field): + """ + Django 1.9 removed usage of Rel objects, see + https://github.com/django/django/pull/4241 + + :param field: Field + :return: remote field + """ + if django.VERSION < (1, 9): + return field.rel + else: + return field.remote_field diff --git a/rest_framework/utils/model_meta.py b/rest_framework/utils/model_meta.py index 253cd5bcc6..af63d83d85 100644 --- a/rest_framework/utils/model_meta.py +++ b/rest_framework/utils/model_meta.py @@ -14,7 +14,8 @@ from django.utils import six from rest_framework.compat import ( - get_all_related_many_to_many_objects, get_all_related_objects + get_all_related_many_to_many_objects, get_all_related_objects, + get_remote_field ) FieldInfo = namedtuple('FieldResult', [ @@ -80,16 +81,16 @@ def get_field_info(model): def _get_pk(opts): pk = opts.pk - while pk.remote_field and pk.remote_field.parent_link: + while get_remote_field(pk) and get_remote_field(pk).parent_link: # If model is a child via multi-table inheritance, use parent's pk. - pk = pk.remote_field.to._meta.pk + pk = get_remote_field(pk).to._meta.pk return pk def _get_fields(opts): fields = OrderedDict() - for field in [field for field in opts.fields if field.serialize and not field.remote_field]: + for field in [field for field in opts.fields if field.serialize and not get_remote_field(field)]: fields[field.name] = field return fields @@ -104,10 +105,10 @@ def _get_forward_relationships(opts): Returns an `OrderedDict` of field names to `RelationInfo`. """ forward_relations = OrderedDict() - for field in [field for field in opts.fields if field.serialize and field.remote_field]: + for field in [field for field in opts.fields if field.serialize and get_remote_field(field)]: forward_relations[field.name] = RelationInfo( model_field=field, - related_model=_resolve_model(field.remote_field.to), + related_model=_resolve_model(get_remote_field(field).to), to_many=False, to_field=_get_to_field(field), has_through_model=False @@ -117,12 +118,12 @@ def _get_forward_relationships(opts): for field in [field for field in opts.many_to_many if field.serialize]: forward_relations[field.name] = RelationInfo( model_field=field, - related_model=_resolve_model(field.remote_field.to), + related_model=_resolve_model(get_remote_field(field).to), to_many=True, # manytomany do not have to_fields to_field=None, has_through_model=( - not field.remote_field.through._meta.auto_created + not get_remote_field(field).through._meta.auto_created ) ) @@ -144,7 +145,7 @@ def _get_reverse_relationships(opts): reverse_relations[accessor_name] = RelationInfo( model_field=None, related_model=related, - to_many=relation.field.remote_field.multiple, + to_many=get_remote_field(relation.field).multiple, to_field=_get_to_field(relation.field), has_through_model=False ) @@ -160,8 +161,8 @@ def _get_reverse_relationships(opts): # manytomany do not have to_fields to_field=None, has_through_model=( - (getattr(relation.field.remote_field, 'through', None) is not None) and - not relation.field.remote_field.through._meta.auto_created + (getattr(get_remote_field(relation.field), 'through', None) is not None) and + not get_remote_field(relation.field).through._meta.auto_created ) ) From 42f701e024d68ee7e3531a28fe7d698c9ac5cd61 Mon Sep 17 00:00:00 2001 From: Justin Plock Date: Sun, 7 Feb 2016 13:46:54 -0500 Subject: [PATCH 3/3] Set the remote_field once. Tests are failing for me locally now, so I want to see what Travis says --- rest_framework/utils/model_meta.py | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/rest_framework/utils/model_meta.py b/rest_framework/utils/model_meta.py index af63d83d85..bbf0b30ed1 100644 --- a/rest_framework/utils/model_meta.py +++ b/rest_framework/utils/model_meta.py @@ -81,9 +81,10 @@ def get_field_info(model): def _get_pk(opts): pk = opts.pk - while get_remote_field(pk) and get_remote_field(pk).parent_link: + remote_field = get_remote_field(pk) + while remote_field and remote_field.parent_link: # If model is a child via multi-table inheritance, use parent's pk. - pk = get_remote_field(pk).to._meta.pk + pk = remote_field.to._meta.pk return pk @@ -106,9 +107,10 @@ def _get_forward_relationships(opts): """ forward_relations = OrderedDict() for field in [field for field in opts.fields if field.serialize and get_remote_field(field)]: + remote_field = get_remote_field(field) forward_relations[field.name] = RelationInfo( model_field=field, - related_model=_resolve_model(get_remote_field(field).to), + related_model=_resolve_model(remote_field.to), to_many=False, to_field=_get_to_field(field), has_through_model=False @@ -116,14 +118,15 @@ def _get_forward_relationships(opts): # Deal with forward many-to-many relationships. for field in [field for field in opts.many_to_many if field.serialize]: + remote_field = get_remote_field(field) forward_relations[field.name] = RelationInfo( model_field=field, - related_model=_resolve_model(get_remote_field(field).to), + related_model=_resolve_model(remote_field.to), to_many=True, # manytomany do not have to_fields to_field=None, has_through_model=( - not get_remote_field(field).through._meta.auto_created + not remote_field.through._meta.auto_created ) ) @@ -142,10 +145,11 @@ def _get_reverse_relationships(opts): for relation in get_all_related_objects(opts): accessor_name = relation.get_accessor_name() related = getattr(relation, 'related_model', relation.model) + remote_field = get_remote_field(relation.field) reverse_relations[accessor_name] = RelationInfo( model_field=None, related_model=related, - to_many=get_remote_field(relation.field).multiple, + to_many=remote_field.multiple, to_field=_get_to_field(relation.field), has_through_model=False ) @@ -154,6 +158,7 @@ def _get_reverse_relationships(opts): for relation in get_all_related_many_to_many_objects(opts): accessor_name = relation.get_accessor_name() related = getattr(relation, 'related_model', relation.model) + remote_field = get_remote_field(relation.field) reverse_relations[accessor_name] = RelationInfo( model_field=None, related_model=related, @@ -161,8 +166,8 @@ def _get_reverse_relationships(opts): # manytomany do not have to_fields to_field=None, has_through_model=( - (getattr(get_remote_field(relation.field), 'through', None) is not None) and - not get_remote_field(relation.field).through._meta.auto_created + (getattr(remote_field, 'through', None) is not None) and + not remote_field.through._meta.auto_created ) )