aboutsummaryrefslogtreecommitdiffstats
path: root/rest_framework
diff options
context:
space:
mode:
authorTom Christie2014-10-08 16:09:37 +0100
committerTom Christie2014-10-08 16:09:37 +0100
commit14ae52a24e93063f77c6010269bf9cd3316627fe (patch)
treec87bede7775b8eaf8fa33ff9e8028575a47fe26c /rest_framework
parent28f3b314f12cbff33c55602c2c5f5f5cce956171 (diff)
downloaddjango-rest-framework-14ae52a24e93063f77c6010269bf9cd3316627fe.tar.bz2
More gradual deprecation
Diffstat (limited to 'rest_framework')
-rw-r--r--rest_framework/request.py16
-rw-r--r--rest_framework/serializers.py71
-rw-r--r--rest_framework/utils/field_mapping.py22
-rw-r--r--rest_framework/utils/model_meta.py4
4 files changed, 99 insertions, 14 deletions
diff --git a/rest_framework/request.py b/rest_framework/request.py
index d80baa70..d4352742 100644
--- a/rest_framework/request.py
+++ b/rest_framework/request.py
@@ -18,6 +18,7 @@ from rest_framework import HTTP_HEADER_ENCODING
from rest_framework import exceptions
from rest_framework.compat import BytesIO
from rest_framework.settings import api_settings
+import warnings
def is_form_media_type(media_type):
@@ -209,6 +210,11 @@ class Request(object):
"""
Synonym for `.query_params`, for backwards compatibility.
"""
+ warnings.warn(
+ "`request.QUERY_PARAMS` is pending deprecation. Use `request.query_params` instead.",
+ PendingDeprecationWarning,
+ stacklevel=1
+ )
return self._request.GET
@property
@@ -225,6 +231,11 @@ class Request(object):
Similar to usual behaviour of `request.POST`, except that it handles
arbitrary parsers, and also works on methods other than POST (eg PUT).
"""
+ warnings.warn(
+ "`request.DATA` is pending deprecation. Use `request.data` instead.",
+ PendingDeprecationWarning,
+ stacklevel=1
+ )
if not _hasattr(self, '_data'):
self._load_data_and_files()
return self._data
@@ -237,6 +248,11 @@ class Request(object):
Similar to usual behaviour of `request.FILES`, except that it handles
arbitrary parsers, and also works on methods other than POST (eg PUT).
"""
+ warnings.warn(
+ "`request.FILES` is pending deprecation. Use `request.data` instead.",
+ PendingDeprecationWarning,
+ stacklevel=1
+ )
if not _hasattr(self, '_files'):
self._load_data_and_files()
return self._files
diff --git a/rest_framework/serializers.py b/rest_framework/serializers.py
index 8513428c..9fcbcba7 100644
--- a/rest_framework/serializers.py
+++ b/rest_framework/serializers.py
@@ -25,6 +25,7 @@ from rest_framework.utils.field_mapping import (
from rest_framework.validators import UniqueTogetherValidator
import copy
import inspect
+import warnings
# Note: We do the following so that users of the framework can use this style:
#
@@ -517,12 +518,24 @@ class ModelSerializer(Serializer):
depth = getattr(self.Meta, 'depth', 0)
extra_kwargs = getattr(self.Meta, 'extra_kwargs', {})
+ extra_kwargs = self._include_additional_options(extra_kwargs)
+
# Retrieve metadata about fields & relationships on the model class.
info = model_meta.get_field_info(model)
# Use the default set of fields if none is supplied explicitly.
if fields is None:
fields = self._get_default_field_names(declared_fields, info)
+ exclude = getattr(self.Meta, 'exclude', None)
+ if exclude is not None:
+ warnings.warn(
+ "The `Meta.exclude` option is pending deprecation. "
+ "Use the explicit `Meta.fields` instead.",
+ PendingDeprecationWarning,
+ stacklevel=3
+ )
+ for field_name in exclude:
+ fields.remove(field_name)
for field_name in fields:
if field_name in declared_fields:
@@ -589,13 +602,69 @@ class ModelSerializer(Serializer):
)
# Populate any kwargs defined in `Meta.extra_kwargs`
- kwargs.update(extra_kwargs.get(field_name, {}))
+ extras = extra_kwargs.get(field_name, {})
+ if extras.get('read_only', False):
+ for attr in [
+ 'required', 'default', 'allow_blank', 'allow_null',
+ 'min_length', 'max_length', 'min_value', 'max_value',
+ 'validators'
+ ]:
+ kwargs.pop(attr, None)
+ kwargs.update(extras)
# Create the serializer field.
ret[field_name] = field_cls(**kwargs)
return ret
+ def _include_additional_options(self, extra_kwargs):
+ read_only_fields = getattr(self.Meta, 'read_only_fields', None)
+ if read_only_fields is not None:
+ for field_name in read_only_fields:
+ kwargs = extra_kwargs.get(field_name, {})
+ kwargs['read_only'] = True
+ extra_kwargs[field_name] = kwargs
+
+ # These are all pending deprecation.
+ write_only_fields = getattr(self.Meta, 'write_only_fields', None)
+ if write_only_fields is not None:
+ warnings.warn(
+ "The `Meta.write_only_fields` option is pending deprecation. "
+ "Use `Meta.extra_kwargs={<field_name>: {'write_only': True}}` instead.",
+ PendingDeprecationWarning,
+ stacklevel=3
+ )
+ for field_name in write_only_fields:
+ kwargs = extra_kwargs.get(field_name, {})
+ kwargs['write_only'] = True
+ extra_kwargs[field_name] = kwargs
+
+ view_name = getattr(self.Meta, 'view_name', None)
+ if view_name is not None:
+ warnings.warn(
+ "The `Meta.view_name` option is pending deprecation. "
+ "Use `Meta.extra_kwargs={'url': {'view_name': ...}}` instead.",
+ PendingDeprecationWarning,
+ stacklevel=3
+ )
+ kwargs = extra_kwargs.get(field_name, {})
+ kwargs['view_name'] = view_name
+ extra_kwargs[api_settings.URL_FIELD_NAME] = kwargs
+
+ lookup_field = getattr(self.Meta, 'lookup_field', None)
+ if lookup_field is not None:
+ warnings.warn(
+ "The `Meta.lookup_field` option is pending deprecation. "
+ "Use `Meta.extra_kwargs={'url': {'lookup_field': ...}}` instead.",
+ PendingDeprecationWarning,
+ stacklevel=3
+ )
+ kwargs = extra_kwargs.get(field_name, {})
+ kwargs['lookup_field'] = lookup_field
+ extra_kwargs[api_settings.URL_FIELD_NAME] = kwargs
+
+ return extra_kwargs
+
def _get_default_field_names(self, declared_fields, model_info):
return (
[model_info.pk.name] +
diff --git a/rest_framework/utils/field_mapping.py b/rest_framework/utils/field_mapping.py
index fd6da699..6db37146 100644
--- a/rest_framework/utils/field_mapping.py
+++ b/rest_framework/utils/field_mapping.py
@@ -71,6 +71,17 @@ def get_field_kwargs(field_name, model_field):
if model_field.help_text:
kwargs['help_text'] = model_field.help_text
+ max_digits = getattr(model_field, 'max_digits', None)
+ if max_digits is not None:
+ kwargs['max_digits'] = max_digits
+
+ decimal_places = getattr(model_field, 'decimal_places', None)
+ if decimal_places is not None:
+ kwargs['decimal_places'] = decimal_places
+
+ if isinstance(model_field, models.TextField):
+ kwargs['style'] = {'type': 'textarea'}
+
if isinstance(model_field, models.AutoField) or not model_field.editable:
# If this field is read-only, then return early.
# Further keyword arguments are not valid.
@@ -86,9 +97,6 @@ def get_field_kwargs(field_name, model_field):
kwargs['choices'] = model_field.flatchoices
return kwargs
- if isinstance(model_field, models.TextField):
- kwargs['style'] = {'type': 'textarea'}
-
if model_field.null and not isinstance(model_field, models.NullBooleanField):
kwargs['allow_null'] = True
@@ -171,14 +179,6 @@ def get_field_kwargs(field_name, model_field):
validator = UniqueValidator(queryset=model_field.model._default_manager)
validator_kwarg.append(validator)
- max_digits = getattr(model_field, 'max_digits', None)
- if max_digits is not None:
- kwargs['max_digits'] = max_digits
-
- decimal_places = getattr(model_field, 'decimal_places', None)
- if decimal_places is not None:
- kwargs['decimal_places'] = decimal_places
-
if validator_kwarg:
kwargs['validators'] = validator_kwarg
diff --git a/rest_framework/utils/model_meta.py b/rest_framework/utils/model_meta.py
index b6c41174..7a95bcdd 100644
--- a/rest_framework/utils/model_meta.py
+++ b/rest_framework/utils/model_meta.py
@@ -107,8 +107,8 @@ def get_field_info(model):
related=relation.model,
to_many=True,
has_through_model=(
- hasattr(relation.field.rel, 'through') and
- not relation.field.rel.through._meta.auto_created
+ (getattr(relation.field.rel, 'through', None) is not None)
+ and not relation.field.rel.through._meta.auto_created
)
)