adding_appendlist_field: adding tranformitive field

This commit is contained in:
HiddenWarrior 2018-10-21 13:59:24 +02:00
parent 2c9c0f1b7f
commit 61379205d4
3 changed files with 78 additions and 1 deletions

View File

@ -1933,3 +1933,19 @@ class ModelField(Field):
if is_protected_type(value):
return value
return self.model_field.value_to_string(obj)
class TransformitiveFieldMixin():
"""
it's an interface to allow any field to change the it's data
from the already database object if using the modelserializer
"""
def apply_transformation(self, instance, data):
"""
the transformation to be done by the inherited field to do it's work
:param instance:
:param data:
:return:
"""
raise NotImplementedError("apply_tranformation is not implement for this field %s" % self.field_name)

View File

@ -29,7 +29,7 @@ from django.utils.translation import ugettext_lazy as _
from rest_framework.compat import Mapping, postgres_fields, unicode_to_repr
from rest_framework.exceptions import ErrorDetail, ValidationError
from rest_framework.fields import get_error_detail, set_value
from rest_framework.fields import get_error_detail, set_value, TransformitiveFieldMixin
from rest_framework.settings import api_settings
from rest_framework.utils import html, model_meta, representation
from rest_framework.utils.field_mapping import (
@ -901,6 +901,20 @@ class ModelSerializer(Serializer):
# "HTTP 201 Created" responses.
url_field_name = None
def to_internal_value(self, data):
"""
adding functionality of changing data sent by the serializer
by the data inside the instance
:param data:
:return:
"""
fields = self._writable_fields
for field in fields:
if self.instance and isinstance(field, TransformitiveFieldMixin):
field.apply_transformation(self.instance, data)
return super(ModelSerializer, self).to_internal_value(data)
# Default `create` and `update` behavior...
def create(self, validated_data):
"""

View File

@ -1274,3 +1274,50 @@ class Issue6110Test(TestCase):
msginitial = ('Got a `TypeError` when calling `Issue6110TestModel.all_objects.create()`.')
with self.assertRaisesMessage(TypeError, msginitial):
Issue6110ModelSerializer().create({'wrong_param': 'wrong_param'})
class TestTransformitiveField(TestCase):
def setUp(self):
self.instance = OneFieldModel(char_field="abc")
def __create_serializer(self,implementor):
class serializer(serializers.ModelSerializer):
char_field = implementor()
class Meta:
model = OneFieldModel
fields = ('char_field')
return serializer
def test_adding_transformitive_field_mixin_without_implementing_the_method(self):
class EmptyImplementor(serializers.TransformitiveFieldMixin,serializers.CharField):
pass
with self.assertRaises(NotImplementedError):
TestSerializer = self.__create_serializer(EmptyImplementor)
serializer = TestSerializer(instance=self.instance, data={})
serializer.save()
def test_adding_transformitive_field_mixin_with_implementing_the_method(self):
class NonEmptyImplementor(serializers.TransformitiveFieldMixin,serializers.CharField):
def apply_transformation(self, instance, data):
data["char_field"] = data["char_field"][0:1]+instance.char_field[0:1]
TestSerializer = self.__create_serializer(NonEmptyImplementor)
serializer = TestSerializer(instance=self.instance, data={"char_field":"bb"})
new_instance = serializer.save()
self.asserEqual(new_instance.char_field,"ba")
def test_if_no_instance_is_passed_no_errors_would_happen(self):
class NonEmptyImplementor(serializers.TransformitiveFieldMixin,serializers.CharField):
def apply_transformation(self, instance, data):
data["char_field"] = data["char_field"][0:1]+instance.char_field[0:1]
TestSerializer = self.__create_serializer(NonEmptyImplementor)
data={"char_field":"bb"}
serializer = TestSerializer()
serializer.to_internal_value(data)