Skip to content

Commit 883efbc

Browse files
rowanseymourtomchristie
authored andcommitted
Case insensitive uniqueness validation (encode#4534)
1 parent 0b373be commit 883efbc

File tree

3 files changed

+6
-4
lines changed

3 files changed

+6
-4
lines changed

docs/api-guide/validators.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ It takes a single required argument, and an optional `messages` argument:
6161

6262
* `queryset` *required* - This is the queryset against which uniqueness should be enforced.
6363
* `message` - The error message that should be used when validation fails.
64+
* `lookup` - The lookup used to find an existing instance with the value being validated. Defaults to `'exact'`.
6465

6566
This validator should be applied to *serializer fields*, like so:
6667

rest_framework/validators.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,10 +42,11 @@ class UniqueValidator(object):
4242
"""
4343
message = _('This field must be unique.')
4444

45-
def __init__(self, queryset, message=None):
45+
def __init__(self, queryset, message=None, lookup='exact'):
4646
self.queryset = queryset
4747
self.serializer_field = None
4848
self.message = message or self.message
49+
self.lookup = lookup
4950

5051
def set_context(self, serializer_field):
5152
"""
@@ -62,7 +63,7 @@ def filter_queryset(self, value, queryset):
6263
"""
6364
Filter the queryset to all instances matching the given attribute.
6465
"""
65-
filter_kwargs = {self.field_name: value}
66+
filter_kwargs = {'%s__%s' % (self.field_name, self.lookup): value}
6667
return qs_filter(queryset, **filter_kwargs)
6768

6869
def exclude_current_instance(self, queryset):

tests/test_validators.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ class RelatedModel(models.Model):
3131

3232
class RelatedModelSerializer(serializers.ModelSerializer):
3333
username = serializers.CharField(source='user.username',
34-
validators=[UniqueValidator(queryset=UniquenessModel.objects.all())]) # NOQA
34+
validators=[UniqueValidator(queryset=UniquenessModel.objects.all(), lookup='iexact')]) # NOQA
3535

3636
class Meta:
3737
model = RelatedModel
@@ -103,7 +103,7 @@ def test_doesnt_pollute_model(self):
103103
AnotherUniquenessModel._meta.get_field('code').validators, [])
104104

105105
def test_related_model_is_unique(self):
106-
data = {'username': 'existing', 'email': 'new-email@example.com'}
106+
data = {'username': 'Existing', 'email': 'new-email@example.com'}
107107
rs = RelatedModelSerializer(data=data)
108108
self.assertFalse(rs.is_valid())
109109
self.assertEqual(rs.errors,

0 commit comments

Comments
 (0)