Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Clean up existing deprecation warnings. #4166

Merged
merged 8 commits into from
Jun 2, 2016
2 changes: 1 addition & 1 deletion rest_framework/authtoken/migrations/0001_initial.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ class Migration(migrations.Migration):
fields=[
('key', models.CharField(primary_key=True, serialize=False, max_length=40)),
('created', models.DateTimeField(auto_now_add=True)),
('user', models.OneToOneField(to=settings.AUTH_USER_MODEL, related_name='auth_token')),
('user', models.OneToOneField(to=settings.AUTH_USER_MODEL, related_name='auth_token', on_delete=models.CASCADE)),
],
options={
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,6 @@ class Migration(migrations.Migration):
migrations.AlterField(
model_name='token',
name='user',
field=models.OneToOneField(to=settings.AUTH_USER_MODEL, verbose_name='User', related_name='auth_token'),
field=models.OneToOneField(to=settings.AUTH_USER_MODEL, verbose_name='User', related_name='auth_token', on_delete=models.CASCADE),
),
]
55 changes: 54 additions & 1 deletion rest_framework/compat.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,13 @@
# flake8: noqa
from __future__ import unicode_literals

import inspect

import django
from django.apps import apps
from django.conf import settings
from django.db import connection, transaction
from django.core.exceptions import ImproperlyConfigured
from django.db import connection, models, transaction
from django.template import Context, RequestContext, Template
from django.utils import six
from django.views.generic import View
Expand Down Expand Up @@ -58,6 +62,7 @@ def distinct(queryset, base):
return queryset.distinct()


# Obtaining manager instances and names from model options differs after 1.10.
def get_names_and_managers(options):
if django.VERSION >= (1, 10):
# Django 1.10 onwards provides a `.managers` property on the Options.
Expand All @@ -75,6 +80,54 @@ def get_names_and_managers(options):
]


# field.rel is deprecated from 1.9 onwards
def get_remote_field(field, **kwargs):
if 'default' in kwargs:
if django.VERSION < (1, 9):
return getattr(field, 'rel', kwargs['default'])
return getattr(field, 'remote_field', kwargs['default'])

if django.VERSION < (1, 9):
return field.rel
return field.remote_field


def _resolve_model(obj):
"""
Resolve supplied `obj` to a Django model class.

`obj` must be a Django model class itself, or a string
representation of one. Useful in situations like GH #1225 where
Django may not have resolved a string-based reference to a model in
another model's foreign key definition.

String representations should have the format:
'appname.ModelName'
"""
if isinstance(obj, six.string_types) and len(obj.split('.')) == 2:
app_name, model_name = obj.split('.')
resolved_model = apps.get_model(app_name, model_name)
if resolved_model is None:
msg = "Django did not return a model for {0}.{1}"
raise ImproperlyConfigured(msg.format(app_name, model_name))
return resolved_model
elif inspect.isclass(obj) and issubclass(obj, models.Model):
return obj
raise ValueError("{0} is not a Django model".format(obj))


def get_related_model(field):
if django.VERSION < (1, 9):
return _resolve_model(field.rel.to)
return field.remote_field.model


def value_from_object(field, obj):
if django.VERSION < (1, 9):
return field._get_val_from_obj(obj)
field.value_from_object(obj)


# contrib.postgres only supported from 1.8 onwards.
try:
from django.contrib.postgres import fields as postgres_fields
Expand Down
8 changes: 5 additions & 3 deletions rest_framework/fields.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,9 @@
from django.utils.translation import ugettext_lazy as _

from rest_framework import ISO_8601
from rest_framework.compat import unicode_repr, unicode_to_repr
from rest_framework.compat import (
get_remote_field, unicode_repr, unicode_to_repr, value_from_object
)
from rest_framework.exceptions import ValidationError
from rest_framework.settings import api_settings
from rest_framework.utils import html, humanize_datetime, representation
Expand Down Expand Up @@ -1674,7 +1676,7 @@ def __init__(self, model_field, **kwargs):
self.validators.append(MaxLengthValidator(max_length, message=message))

def to_internal_value(self, data):
rel = getattr(self.model_field, 'rel', None)
rel = get_remote_field(self.model_field, default=None)
if rel is not None:
return rel.to._meta.get_field(rel.field_name).to_python(data)
return self.model_field.to_python(data)
Expand All @@ -1685,7 +1687,7 @@ def get_attribute(self, obj):
return obj

def to_representation(self, obj):
value = self.model_field._get_val_from_obj(obj)
value = value_from_object(self.model_field, obj)
if is_protected_type(value):
return value
return self.model_field.value_to_string(obj)
2 changes: 2 additions & 0 deletions rest_framework/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -1153,6 +1153,7 @@ class NestedSerializer(ModelSerializer):
class Meta:
model = relation_info.related_model
depth = nested_depth - 1
fields = '__all__'

field_class = NestedSerializer
field_kwargs = get_nested_relation_kwargs(relation_info)
Expand Down Expand Up @@ -1469,6 +1470,7 @@ class NestedSerializer(HyperlinkedModelSerializer):
class Meta:
model = relation_info.related_model
depth = nested_depth - 1
fields = '__all__'

field_class = NestedSerializer
field_kwargs = get_nested_relation_kwargs(relation_info)
Expand Down
53 changes: 14 additions & 39 deletions rest_framework/utils/model_meta.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,9 @@

Usage: `get_field_info(model)` returns a `FieldInfo` instance.
"""
import inspect
from collections import OrderedDict, namedtuple

from django.apps import apps
from django.core.exceptions import ImproperlyConfigured
from django.db import models
from django.utils import six
from rest_framework.compat import get_related_model, get_remote_field

FieldInfo = namedtuple('FieldResult', [
'pk', # Model field instance
Expand All @@ -31,30 +27,6 @@
])


def _resolve_model(obj):
"""
Resolve supplied `obj` to a Django model class.

`obj` must be a Django model class itself, or a string
representation of one. Useful in situations like GH #1225 where
Django may not have resolved a string-based reference to a model in
another model's foreign key definition.

String representations should have the format:
'appname.ModelName'
"""
if isinstance(obj, six.string_types) and len(obj.split('.')) == 2:
app_name, model_name = obj.split('.')
resolved_model = apps.get_model(app_name, model_name)
if resolved_model is None:
msg = "Django did not return a model for {0}.{1}"
raise ImproperlyConfigured(msg.format(app_name, model_name))
return resolved_model
elif inspect.isclass(obj) and issubclass(obj, models.Model):
return obj
raise ValueError("{0} is not a Django model".format(obj))


def get_field_info(model):
"""
Given a model class, returns a `FieldInfo` instance, which is a
Expand All @@ -76,16 +48,19 @@ def get_field_info(model):

def _get_pk(opts):
pk = opts.pk
while pk.rel and pk.rel.parent_link:
rel = get_remote_field(pk)

while rel and rel.parent_link:
# If model is a child via multi-table inheritance, use parent's pk.
pk = pk.rel.to._meta.pk
pk = get_related_model(pk)._meta.pk
rel = get_remote_field(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 get_remote_field(field)]:
fields[field.name] = field

return fields
Expand All @@ -100,10 +75,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 get_remote_field(field)]:
forward_relations[field.name] = RelationInfo(
model_field=field,
related_model=_resolve_model(field.rel.to),
related_model=get_related_model(field),
to_many=False,
to_field=_get_to_field(field),
has_through_model=False
Expand All @@ -113,12 +88,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=get_related_model(field),
to_many=True,
# manytomany do not have to_fields
to_field=None,
has_through_model=(
not field.rel.through._meta.auto_created
not get_remote_field(field).through._meta.auto_created
)
)

Expand All @@ -141,7 +116,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=get_remote_field(relation.field).multiple,
to_field=_get_to_field(relation.field),
has_through_model=False
)
Expand All @@ -158,8 +133,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(get_remote_field(relation.field), 'through', None) is not None) and
not get_remote_field(relation.field).through._meta.auto_created
)
)

Expand Down
2 changes: 1 addition & 1 deletion tests/test_authentication.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@

class CustomToken(models.Model):
key = models.CharField(max_length=40, primary_key=True)
user = models.OneToOneField(User)
user = models.OneToOneField(User, on_delete=models.CASCADE)


class CustomTokenAuthentication(TokenAuthentication):
Expand Down
8 changes: 6 additions & 2 deletions tests/test_filters.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
class FilterableItemSerializer(serializers.ModelSerializer):
class Meta:
model = FilterableItem
fields = '__all__'

# Basic filter on a list view.
class FilterFieldsRootView(generics.ListCreateAPIView):
Expand Down Expand Up @@ -336,6 +337,7 @@ class SearchFilterModel(models.Model):
class SearchFilterSerializer(serializers.ModelSerializer):
class Meta:
model = SearchFilterModel
fields = '__all__'


class SearchFilterTests(TestCase):
Expand Down Expand Up @@ -461,6 +463,7 @@ class SearchFilterModelM2M(models.Model):
class SearchFilterM2MSerializer(serializers.ModelSerializer):
class Meta:
model = SearchFilterModelM2M
fields = '__all__'


class SearchFilterM2MTests(TestCase):
Expand Down Expand Up @@ -504,13 +507,13 @@ class OrderingFilterModel(models.Model):


class OrderingFilterRelatedModel(models.Model):
related_object = models.ForeignKey(OrderingFilterModel,
related_name="relateds")
related_object = models.ForeignKey(OrderingFilterModel, related_name="relateds", on_delete=models.CASCADE)


class OrderingFilterSerializer(serializers.ModelSerializer):
class Meta:
model = OrderingFilterModel
fields = '__all__'


class DjangoFilterOrderingModel(models.Model):
Expand All @@ -524,6 +527,7 @@ class Meta:
class DjangoFilterOrderingSerializer(serializers.ModelSerializer):
class Meta:
model = DjangoFilterOrderingModel
fields = '__all__'


class DjangoFilterOrderingTests(TestCase):
Expand Down
4 changes: 4 additions & 0 deletions tests/test_generics.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,11 +33,13 @@ class Comment(RESTFrameworkModel):
class BasicSerializer(serializers.ModelSerializer):
class Meta:
model = BasicModel
fields = '__all__'


class ForeignKeySerializer(serializers.ModelSerializer):
class Meta:
model = ForeignKeySource
fields = '__all__'


class SlugSerializer(serializers.ModelSerializer):
Expand Down Expand Up @@ -414,6 +416,7 @@ class ClassASerializer(serializers.ModelSerializer):

class Meta:
model = ClassA
fields = '__all__'


class ExampleView(generics.ListCreateAPIView):
Expand Down Expand Up @@ -461,6 +464,7 @@ class Meta:
class DynamicSerializer(serializers.ModelSerializer):
class Meta:
model = TwoFieldModel
fields = '__all__'
return DynamicSerializer


Expand Down
1 change: 1 addition & 0 deletions tests/test_metadata.py
Original file line number Diff line number Diff line change
Expand Up @@ -300,6 +300,7 @@ class ExampleSerializer(serializers.ModelSerializer):

class Meta:
model = Parent
fields = '__all__'

class ExampleView(views.APIView):
"""Example view."""
Expand Down
Loading