From f88bd2979abc12767ae0d2c3101e632c6e920657 Mon Sep 17 00:00:00 2001 From: Aider Ibragimov Date: Tue, 13 Oct 2015 18:39:57 +0300 Subject: [PATCH 1/2] fix PostgreSQL fields DataError in unique validator --- rest_framework/validators.py | 10 +++++++++- tests/test_validators.py | 8 ++++++++ 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/rest_framework/validators.py b/rest_framework/validators.py index a1771a92e8..79cdbf4c81 100644 --- a/rest_framework/validators.py +++ b/rest_framework/validators.py @@ -8,6 +8,7 @@ """ from __future__ import unicode_literals +from django.db import DataError from django.utils.translation import ugettext_lazy as _ from rest_framework.compat import unicode_to_repr @@ -59,7 +60,14 @@ def __call__(self, value): queryset = self.queryset queryset = self.filter_queryset(value, queryset) queryset = self.exclude_current_instance(queryset) - if queryset.exists(): + + # catch DataError for PostgrSQL fields + try: + exists = queryset.exists() + except DataError: + return + + if exists: raise ValidationError(self.message) def __repr__(self): diff --git a/tests/test_validators.py b/tests/test_validators.py index acaaf57432..347f9b723c 100644 --- a/tests/test_validators.py +++ b/tests/test_validators.py @@ -15,6 +15,7 @@ def dedent(blocktext): class UniquenessModel(models.Model): username = models.CharField(unique=True, max_length=100) + ip = models.GenericIPAddressField(protocol='IPv4', unique=True, blank=True, null=True) class UniquenessSerializer(serializers.ModelSerializer): @@ -41,6 +42,7 @@ def test_repr(self): UniquenessSerializer(): id = IntegerField(label='ID', read_only=True) username = CharField(max_length=100, validators=[]) + ip = IPAddressField(allow_null=True, required=False, validators=[, ]) """) assert repr(serializer) == expected @@ -73,6 +75,12 @@ def test_doesnt_pollute_model(self): self.assertEqual( AnotherUniquenessModel._meta.get_field('code').validators, []) + def test_data_error(self): + data = {'ip': 'test', 'username': 'test'} + serializer = UniquenessSerializer(data=data) + assert not serializer.is_valid() + assert serializer.errors == {'ip': [u'Enter a valid IPv4 address.', u'Enter a valid IPv4 or IPv6 address.']} + # Tests for `UniqueTogetherValidator` # ----------------------------------- From 3315ec72a9ede4f0bf0b90c8cb8552eb2c349167 Mon Sep 17 00:00:00 2001 From: Aider Ibragimov Date: Wed, 14 Oct 2015 12:57:49 +0300 Subject: [PATCH 2/2] fix ci build, make more clear flow --- rest_framework/validators.py | 2 +- tests/test_validators.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/rest_framework/validators.py b/rest_framework/validators.py index 79cdbf4c81..7042b4d6cb 100644 --- a/rest_framework/validators.py +++ b/rest_framework/validators.py @@ -65,7 +65,7 @@ def __call__(self, value): try: exists = queryset.exists() except DataError: - return + exists = False if exists: raise ValidationError(self.message) diff --git a/tests/test_validators.py b/tests/test_validators.py index 347f9b723c..ad91f32717 100644 --- a/tests/test_validators.py +++ b/tests/test_validators.py @@ -79,7 +79,7 @@ def test_data_error(self): data = {'ip': 'test', 'username': 'test'} serializer = UniquenessSerializer(data=data) assert not serializer.is_valid() - assert serializer.errors == {'ip': [u'Enter a valid IPv4 address.', u'Enter a valid IPv4 or IPv6 address.']} + assert serializer.errors == {'ip': ['Enter a valid IPv4 address.', 'Enter a valid IPv4 or IPv6 address.']} # Tests for `UniqueTogetherValidator`