diff options
| -rw-r--r-- | docs/tutorial/5-relationships-and-hyperlinked-apis.md | 2 | ||||
| -rw-r--r-- | rest_framework/fields.py | 11 | ||||
| -rw-r--r-- | rest_framework/utils/field_mapping.py | 2 | ||||
| -rw-r--r-- | tests/test_validators.py | 20 |
4 files changed, 27 insertions, 8 deletions
diff --git a/docs/tutorial/5-relationships-and-hyperlinked-apis.md b/docs/tutorial/5-relationships-and-hyperlinked-apis.md index 58422929..57e3b6c5 100644 --- a/docs/tutorial/5-relationships-and-hyperlinked-apis.md +++ b/docs/tutorial/5-relationships-and-hyperlinked-apis.md @@ -85,7 +85,7 @@ We can easily re-write our existing serializers to use hyperlinking. In your `sn class UserSerializer(serializers.HyperlinkedModelSerializer): - snippets = serializers.HyperlinkedRelatedField(many=True, view_name='snippet-detail') + snippets = serializers.HyperlinkedRelatedField(many=True, view_name='snippet-detail', read_only=True) class Meta: model = User diff --git a/rest_framework/fields.py b/rest_framework/fields.py index 99498da7..15e59861 100644 --- a/rest_framework/fields.py +++ b/rest_framework/fields.py @@ -15,6 +15,7 @@ from rest_framework.compat import ( from rest_framework.exceptions import ValidationError from rest_framework.settings import api_settings from rest_framework.utils import html, representation, humanize_datetime +import collections import copy import datetime import decimal @@ -60,14 +61,12 @@ def get_attribute(instance, attrs): # Break out early if we get `None` at any point in a nested lookup. return None try: - instance = getattr(instance, attr) + if isinstance(instance, collections.Mapping): + instance = instance[attr] + else: + instance = getattr(instance, attr) except ObjectDoesNotExist: return None - except AttributeError as exc: - try: - return instance[attr] - except (KeyError, TypeError, AttributeError): - raise exc if is_simple_callable(instance): instance = instance() return instance diff --git a/rest_framework/utils/field_mapping.py b/rest_framework/utils/field_mapping.py index 86ceff31..fca97b4b 100644 --- a/rest_framework/utils/field_mapping.py +++ b/rest_framework/utils/field_mapping.py @@ -59,7 +59,7 @@ def get_field_kwargs(field_name, model_field): Creates a default instance of a basic non-relational field. """ kwargs = {} - validator_kwarg = model_field.validators + validator_kwarg = list(model_field.validators) # The following will only be used by ModelField classes. # Gets removed for everything else. diff --git a/tests/test_validators.py b/tests/test_validators.py index 5d92b284..072cec36 100644 --- a/tests/test_validators.py +++ b/tests/test_validators.py @@ -20,6 +20,15 @@ class UniquenessSerializer(serializers.ModelSerializer): model = UniquenessModel +class AnotherUniquenessModel(models.Model): + code = models.IntegerField(unique=True) + + +class AnotherUniquenessSerializer(serializers.ModelSerializer): + class Meta: + model = AnotherUniquenessModel + + class TestUniquenessValidation(TestCase): def setUp(self): self.instance = UniquenessModel.objects.create(username='existing') @@ -51,6 +60,17 @@ class TestUniquenessValidation(TestCase): assert serializer.is_valid() assert serializer.validated_data == {'username': 'existing'} + def test_doesnt_pollute_model(self): + instance = AnotherUniquenessModel.objects.create(code='100') + serializer = AnotherUniquenessSerializer(instance) + self.assertEqual( + AnotherUniquenessModel._meta.get_field('code').validators, []) + + # Accessing data shouldn't effect validators on the model + serializer.data + self.assertEqual( + AnotherUniquenessModel._meta.get_field('code').validators, []) + # Tests for `UniqueTogetherValidator` # ----------------------------------- |
