diff --git a/rest_framework/utils/field_mapping.py b/rest_framework/utils/field_mapping.py index d35caca0c7..6637ce366b 100644 --- a/rest_framework/utils/field_mapping.py +++ b/rest_framework/utils/field_mapping.py @@ -208,7 +208,11 @@ def get_field_kwargs(field_name, model_field): if isinstance(model_field, models.GenericIPAddressField): validator_kwarg = [ validator for validator in validator_kwarg - if validator is not validators.validate_ipv46_address + if validator not in ( + validators.validate_ipv46_address, + validators.validate_ipv4_address, + validators.validate_ipv6_address, + ) ] # Our decimal validation is handled in the field code, not validator code. if isinstance(model_field, models.DecimalField): diff --git a/tests/test_model_serializer.py b/tests/test_model_serializer.py index 0e291a2de8..abb86b78cc 100644 --- a/tests/test_model_serializer.py +++ b/tests/test_model_serializer.py @@ -439,6 +439,42 @@ class Meta: 'Unexpected number of validation errors: ' '{}'.format(s.errors)) + def test_ip_address_validation_with_protocol_ipv4(self): + class IPAddressFieldModel(models.Model): + address = models.GenericIPAddressField(protocol='IPv4') + + class Meta: + app_label = 'test_model_serializer' + + class TestSerializer(serializers.ModelSerializer): + class Meta: + model = IPAddressFieldModel + fields = '__all__' + + s = TestSerializer(data={'address': 'not an ip address'}) + self.assertFalse(s.is_valid()) + self.assertEqual(1, len(s.errors['address']), + 'Unexpected number of validation errors: ' + '{}'.format(s.errors)) + + def test_ip_address_validation_with_protocol_ipv6(self): + class IPAddressFieldModel(models.Model): + address = models.GenericIPAddressField(protocol='IPv6') + + class Meta: + app_label = 'test_model_serializer' + + class TestSerializer(serializers.ModelSerializer): + class Meta: + model = IPAddressFieldModel + fields = '__all__' + + s = TestSerializer(data={'address': 'not an ip address'}) + self.assertFalse(s.is_valid()) + self.assertEqual(1, len(s.errors['address']), + 'Unexpected number of validation errors: ' + '{}'.format(s.errors)) + @pytest.mark.skipif('not postgres_fields') class TestPosgresFieldsMapping(TestCase):