aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--docs/tutorial/5-relationships-and-hyperlinked-apis.md2
-rw-r--r--rest_framework/fields.py11
-rw-r--r--rest_framework/utils/field_mapping.py2
-rw-r--r--tests/test_validators.py20
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`
# -----------------------------------