diff --git a/django/contrib/gis/serializers/geojson.py b/django/contrib/gis/serializers/geojson.py index eb0533bdeda..9c15b496767 100644 --- a/django/contrib/gis/serializers/geojson.py +++ b/django/contrib/gis/serializers/geojson.py @@ -60,7 +60,7 @@ class Serializer(JSONSerializer): def handle_field(self, obj, field): if field.name == self.geometry_field: - self._geometry = field._get_val_from_obj(obj) + self._geometry = field.value_from_object(obj) else: super(Serializer, self).handle_field(obj, field) diff --git a/django/contrib/postgres/fields/array.py b/django/contrib/postgres/fields/array.py index f9242f086b4..9daea8e5c7b 100644 --- a/django/contrib/postgres/fields/array.py +++ b/django/contrib/postgres/fields/array.py @@ -90,7 +90,7 @@ class ArrayField(Field): def value_to_string(self, obj): values = [] - vals = self._get_val_from_obj(obj) + vals = self.value_from_object(obj) base_field = self.base_field for val in vals: diff --git a/django/contrib/postgres/fields/hstore.py b/django/contrib/postgres/fields/hstore.py index c87eef3bef5..366c40052e2 100644 --- a/django/contrib/postgres/fields/hstore.py +++ b/django/contrib/postgres/fields/hstore.py @@ -42,8 +42,7 @@ class HStoreField(Field): return value def value_to_string(self, obj): - value = self._get_val_from_obj(obj) - return json.dumps(value) + return json.dumps(self.value_from_object(obj)) def formfield(self, **kwargs): defaults = { diff --git a/django/contrib/postgres/fields/jsonb.py b/django/contrib/postgres/fields/jsonb.py index eaf3e98d36a..d580ea2efdd 100644 --- a/django/contrib/postgres/fields/jsonb.py +++ b/django/contrib/postgres/fields/jsonb.py @@ -50,7 +50,7 @@ class JSONField(Field): ) def value_to_string(self, obj): - value = self._get_val_from_obj(obj) + value = self.value_from_object(obj) return value def formfield(self, **kwargs): diff --git a/django/contrib/postgres/fields/ranges.py b/django/contrib/postgres/fields/ranges.py index 13ba606c79a..5f9e13508ee 100644 --- a/django/contrib/postgres/fields/ranges.py +++ b/django/contrib/postgres/fields/ranges.py @@ -43,7 +43,7 @@ class RangeField(models.Field): self.base_field.set_attributes_from_name(name) def value_to_string(self, obj): - value = self._get_val_from_obj(obj) + value = self.value_from_object(obj) if value is None: return None if value.isempty: diff --git a/django/core/serializers/python.py b/django/core/serializers/python.py index 55c62923430..ff506d50cb7 100644 --- a/django/core/serializers/python.py +++ b/django/core/serializers/python.py @@ -45,7 +45,7 @@ class Serializer(base.Serializer): return data def handle_field(self, obj, field): - value = field._get_val_from_obj(obj) + value = field.value_from_object(obj) # Protected types (i.e., primitives like None, numbers, dates, # and Decimals) are passed through as is. All other values are # converted to string first. diff --git a/django/db/models/fields/__init__.py b/django/db/models/fields/__init__.py index 5ae1aa3dc72..2c9ab104ccc 100644 --- a/django/db/models/fields/__init__.py +++ b/django/db/models/fields/__init__.py @@ -29,7 +29,9 @@ from django.utils.datastructures import DictWrapper from django.utils.dateparse import ( parse_date, parse_datetime, parse_duration, parse_time, ) -from django.utils.deprecation import RemovedInDjango20Warning +from django.utils.deprecation import ( + RemovedInDjango20Warning, warn_about_renamed_method, +) from django.utils.duration import duration_string from django.utils.encoding import ( force_bytes, force_text, python_2_unicode_compatible, smart_text, @@ -832,6 +834,10 @@ class Field(RegisterLookupMixin): first_choice = blank_choice if include_blank else [] return first_choice + list(self.flatchoices) + @warn_about_renamed_method( + 'Field', '_get_val_from_obj', 'value_from_object', + RemovedInDjango20Warning + ) def _get_val_from_obj(self, obj): if obj is not None: return getattr(obj, self.attname) @@ -843,7 +849,7 @@ class Field(RegisterLookupMixin): Returns a string value of this field from the passed obj. This is used by the serialization framework. """ - return smart_text(self._get_val_from_obj(obj)) + return smart_text(self.value_from_object(obj)) def _get_flatchoices(self): """Flattened version of choices tuple.""" @@ -1298,7 +1304,7 @@ class DateField(DateTimeCheckMixin, Field): return connection.ops.adapt_datefield_value(value) def value_to_string(self, obj): - val = self._get_val_from_obj(obj) + val = self.value_from_object(obj) return '' if val is None else val.isoformat() def formfield(self, **kwargs): @@ -1458,7 +1464,7 @@ class DateTimeField(DateField): return connection.ops.adapt_datetimefield_value(value) def value_to_string(self, obj): - val = self._get_val_from_obj(obj) + val = self.value_from_object(obj) return '' if val is None else val.isoformat() def formfield(self, **kwargs): @@ -1680,7 +1686,7 @@ class DurationField(Field): return converters + super(DurationField, self).get_db_converters(connection) def value_to_string(self, obj): - val = self._get_val_from_obj(obj) + val = self.value_from_object(obj) return '' if val is None else duration_string(val) def formfield(self, **kwargs): @@ -2288,7 +2294,7 @@ class TimeField(DateTimeCheckMixin, Field): return connection.ops.adapt_timefield_value(value) def value_to_string(self, obj): - val = self._get_val_from_obj(obj) + val = self.value_from_object(obj) return '' if val is None else val.isoformat() def formfield(self, **kwargs): @@ -2355,7 +2361,7 @@ class BinaryField(Field): def value_to_string(self, obj): """Binary data is serialized as base64""" - return b64encode(force_bytes(self._get_val_from_obj(obj))).decode('ascii') + return b64encode(force_bytes(self.value_from_object(obj))).decode('ascii') def to_python(self, value): # If it's a string, it should be base64-encoded data diff --git a/docs/howto/custom-model-fields.txt b/docs/howto/custom-model-fields.txt index 95c1cd68ab1..c0cde0e99ba 100644 --- a/docs/howto/custom-model-fields.txt +++ b/docs/howto/custom-model-fields.txt @@ -705,15 +705,16 @@ Converting field data for serialization ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ To customize how the values are serialized by a serializer, you can override -:meth:`~Field.value_to_string`. Calling ``Field._get_val_from_obj(obj)`` is the -best way to get the value serialized. For example, since our ``HandField`` uses -strings for its data storage anyway, we can reuse some existing conversion code:: +:meth:`~Field.value_to_string`. Using ``value_from_object()`` is the best way +to get the field's value prior to serialization. For example, since our +``HandField`` uses strings for its data storage anyway, we can reuse some +existing conversion code:: class HandField(models.Field): # ... def value_to_string(self, obj): - value = self._get_val_from_obj(obj) + value = self.value_from_object(obj) return self.get_prep_value(value) Some general advice diff --git a/docs/internals/deprecation.txt b/docs/internals/deprecation.txt index 63171d09b50..f597963d8c2 100644 --- a/docs/internals/deprecation.txt +++ b/docs/internals/deprecation.txt @@ -79,6 +79,9 @@ details on these changes. * Support for setting a URL instance namespace without an application namespace will be removed. +* ``Field._get_val_from_obj()`` will be removed in favor of + ``Field.value_from_object()``. + .. _deprecation-removed-in-1.10: 1.10 diff --git a/docs/releases/1.9.txt b/docs/releases/1.9.txt index 27893fb97c9..a9217b6145f 100644 --- a/docs/releases/1.9.txt +++ b/docs/releases/1.9.txt @@ -1001,6 +1001,9 @@ Miscellaneous * :class:`~django.core.signing.Signer` now issues a warning if an invalid separator is used. This will become an exception in Django 1.10. +* ``django.db.models.Field._get_val_from_obj()`` is deprecated in favor of + ``Field.value_from_object()``. + .. removed-features-1.9: Features removed in 1.9 diff --git a/tests/serializers/models.py b/tests/serializers/models.py index 5e7a31902eb..4e2251ca187 100644 --- a/tests/serializers/models.py +++ b/tests/serializers/models.py @@ -141,7 +141,7 @@ class TeamField(models.CharField): return Team(value) def value_to_string(self, obj): - return self._get_val_from_obj(obj).to_string() + return self.value_from_object(obj).to_string() def deconstruct(self): name, path, args, kwargs = super(TeamField, self).deconstruct()