diff --git a/docs/topics/credits.md b/docs/topics/credits.md index b4bd3561e..3f0ee429c 100644 --- a/docs/topics/credits.md +++ b/docs/topics/credits.md @@ -141,6 +141,7 @@ The following people have helped make REST framework great. * David Medina - [copitux] * Areski Belaid - [areski] * Ethan Freman - [mindlace] +* David Sanders - [davesque] Many thanks to everyone who's contributed to the project. @@ -318,3 +319,5 @@ You can also contact [@_tomchristie][twitter] directly on twitter. [copitux]: https://github.com/copitux [areski]: https://github.com/areski [mindlace]: https://github.com/mindlace +[davesque]: https://github.com/davesque + diff --git a/rest_framework/fields.py b/rest_framework/fields.py index 32e4c4ae4..35848b4ce 100644 --- a/rest_framework/fields.py +++ b/rest_framework/fields.py @@ -336,9 +336,13 @@ class ModelField(WritableField): raise ValueError("ModelField requires 'model_field' kwarg") self.min_length = kwargs.pop('min_length', - getattr(self.model_field, 'min_length', None)) + getattr(self.model_field, 'min_length', None)) self.max_length = kwargs.pop('max_length', - getattr(self.model_field, 'max_length', None)) + getattr(self.model_field, 'max_length', None)) + self.min_value = kwargs.pop('min_value', + getattr(self.model_field, 'min_value', None)) + self.max_value = kwargs.pop('max_value', + getattr(self.model_field, 'max_value', None)) super(ModelField, self).__init__(*args, **kwargs) @@ -346,6 +350,10 @@ class ModelField(WritableField): self.validators.append(validators.MinLengthValidator(self.min_length)) if self.max_length is not None: self.validators.append(validators.MaxLengthValidator(self.max_length)) + if self.min_value is not None: + self.validators.append(validators.MinValueValidator(self.min_value)) + if self.max_value is not None: + self.validators.append(validators.MaxValueValidator(self.max_value)) def from_native(self, value): rel = getattr(self.model_field, "rel", None) diff --git a/rest_framework/generics.py b/rest_framework/generics.py index 80efad013..99e9782e2 100644 --- a/rest_framework/generics.py +++ b/rest_framework/generics.py @@ -212,7 +212,7 @@ class GenericAPIView(views.APIView): You may want to override this if you need to provide different serializations depending on the incoming request. - (Eg. admins get full serialization, others get basic serilization) + (Eg. admins get full serialization, others get basic serialization) """ serializer_class = self.serializer_class if serializer_class is not None: diff --git a/rest_framework/tests/test_fields.py b/rest_framework/tests/test_fields.py index 69a0468e0..6836ec86f 100644 --- a/rest_framework/tests/test_fields.py +++ b/rest_framework/tests/test_fields.py @@ -866,3 +866,33 @@ class FieldCallableDefault(TestCase): into = {} field.field_from_native({}, {}, 'field', into) self.assertEqual(into, {'field': 'foo bar'}) + + +class CustomIntegerField(TestCase): + """ + Test that custom fields apply min_value and max_value constraints + """ + def test_custom_fields_can_be_validated_for_value(self): + + class MoneyField(models.PositiveIntegerField): + pass + + class EntryModel(models.Model): + bank = MoneyField(validators=[validators.MaxValueValidator(100)]) + + class EntrySerializer(serializers.ModelSerializer): + class Meta: + model = EntryModel + + entry = EntryModel(bank=1) + + serializer = EntrySerializer(entry, data={"bank": 11}) + self.assertTrue(serializer.is_valid()) + + serializer = EntrySerializer(entry, data={"bank": -1}) + self.assertFalse(serializer.is_valid()) + + serializer = EntrySerializer(entry, data={"bank": 101}) + self.assertFalse(serializer.is_valid()) + +