diff options
| author | Stephan Groß | 2012-11-21 03:00:02 -0800 | 
|---|---|---|
| committer | Stephan Groß | 2012-11-21 03:00:02 -0800 | 
| commit | 196fa5e94f5348dbb3873a5c87561416b16ea013 (patch) | |
| tree | 36ef44691a8f8bf4b18e080c6e2e9c470198bdfc | |
| parent | 3268c67343f6fc6364a0127a7bfabeb907a4751d (diff) | |
| parent | 03100168ff96dd4a09ee7c8a5a63b294abe99dfe (diff) | |
| download | django-rest-framework-196fa5e94f5348dbb3873a5c87561416b16ea013.tar.bz2 | |
Merge pull request #436 from minddust/regex_field
added RegexField
| -rw-r--r-- | docs/api-guide/fields.md | 10 | ||||
| -rw-r--r-- | docs/topics/release-notes.md | 7 | ||||
| -rw-r--r-- | rest_framework/fields.py | 29 | ||||
| -rw-r--r-- | rest_framework/tests/models.py | 5 | ||||
| -rw-r--r-- | rest_framework/tests/serializer.py | 28 | 
5 files changed, 75 insertions, 4 deletions
diff --git a/docs/api-guide/fields.md b/docs/api-guide/fields.md index 914d0861..1d4c34cb 100644 --- a/docs/api-guide/fields.md +++ b/docs/api-guide/fields.md @@ -153,6 +153,16 @@ A text representation, validates the text to be a valid e-mail address.  Corresponds to `django.db.models.fields.EmailField` +## RegexField + +A text representation, that validates the given value matches against a certain regular expression. + +Uses Django's `django.core.validators.RegexValidator` for validation. + +Corresponds to `django.forms.fields.RegexField` + +**Signature:** `RegexField(regex, max_length=None, min_length=None)` +  ## DateField  A date representation. diff --git a/docs/topics/release-notes.md b/docs/topics/release-notes.md index 0b8a7a8f..c641a1b3 100644 --- a/docs/topics/release-notes.md +++ b/docs/topics/release-notes.md @@ -6,10 +6,11 @@  ## Master -* Added `SerializerMethodField` +* Added `RegexField`. +* Added `SerializerMethodField`.  * Serializer performance improvements. -* Added `obtain_token_view` to get tokens when using `TokenAuthentication` -* Bugfix: Django 1.5 configurable user support for `TokenAuthentication` +* Added `obtain_token_view` to get tokens when using `TokenAuthentication`. +* Bugfix: Django 1.5 configurable user support for `TokenAuthentication`.  ## 2.1.3 diff --git a/rest_framework/fields.py b/rest_framework/fields.py index 9dce0143..25d98645 100644 --- a/rest_framework/fields.py +++ b/rest_framework/fields.py @@ -1,6 +1,7 @@  import copy  import datetime  import inspect +import re  import warnings  from io import BytesIO @@ -802,6 +803,34 @@ class EmailField(CharField):          return result +class RegexField(CharField): +    type_name = 'RegexField' + +    def __init__(self, regex, max_length=None, min_length=None, *args, **kwargs): +        super(RegexField, self).__init__(max_length, min_length, *args, **kwargs) +        self.regex = regex + +    def _get_regex(self): +        return self._regex + +    def _set_regex(self, regex): +        if isinstance(regex, basestring): +            regex = re.compile(regex) +        self._regex = regex +        if hasattr(self, '_regex_validator') and self._regex_validator in self.validators: +            self.validators.remove(self._regex_validator) +        self._regex_validator = validators.RegexValidator(regex=regex) +        self.validators.append(self._regex_validator) + +    regex = property(_get_regex, _set_regex) + +    def __deepcopy__(self, memo): +        result = copy.copy(self) +        memo[id(self)] = result +        result.validators = self.validators[:] +        return result + +  class DateField(WritableField):      type_name = 'DateField' diff --git a/rest_framework/tests/models.py b/rest_framework/tests/models.py index 3704cda7..c35861c6 100644 --- a/rest_framework/tests/models.py +++ b/rest_framework/tests/models.py @@ -165,3 +165,8 @@ class BlankFieldModel(RESTFrameworkModel):  # Model for issue #380  class OptionalRelationModel(RESTFrameworkModel):      other = models.ForeignKey('OptionalRelationModel', blank=True, null=True) + + +# Model for RegexField +class Book(RESTFrameworkModel): +    isbn = models.CharField(max_length=13) diff --git a/rest_framework/tests/serializer.py b/rest_framework/tests/serializer.py index 656bc1dd..520029ec 100644 --- a/rest_framework/tests/serializer.py +++ b/rest_framework/tests/serializer.py @@ -2,7 +2,7 @@ import datetime  from django.test import TestCase  from rest_framework import serializers  from rest_framework.tests.models import (ActionItem, Anchor, BasicModel, -    BlankFieldModel, BlogPost, CallableDefaultValueModel, DefaultValueModel, +    BlankFieldModel, BlogPost, Book, CallableDefaultValueModel, DefaultValueModel,      ManyToManyModel, Person, ReadOnlyManyToManyModel) @@ -40,6 +40,13 @@ class CommentSerializer(serializers.Serializer):          return instance +class BookSerializer(serializers.ModelSerializer): +    isbn = serializers.RegexField(regex=r'^[0-9]{13}$', error_messages={'invalid': 'isbn has to be exact 13 numbers'}) + +    class Meta: +        model = Book + +  class ActionItemSerializer(serializers.ModelSerializer):      class Meta: @@ -258,6 +265,25 @@ class ValidationTests(TestCase):          self.assertEquals(serializer.errors, {'info': [u'Ensure this value has at most 12 characters (it has 13).']}) +class RegexValidationTest(TestCase): +    def test_create_failed(self): +        serializer = BookSerializer(data={'isbn': '1234567890'}) +        self.assertFalse(serializer.is_valid()) +        self.assertEquals(serializer.errors, {'isbn': [u'isbn has to be exact 13 numbers']}) + +        serializer = BookSerializer(data={'isbn': '12345678901234'}) +        self.assertFalse(serializer.is_valid()) +        self.assertEquals(serializer.errors, {'isbn': [u'isbn has to be exact 13 numbers']}) + +        serializer = BookSerializer(data={'isbn': 'abcdefghijklm'}) +        self.assertFalse(serializer.is_valid()) +        self.assertEquals(serializer.errors, {'isbn': [u'isbn has to be exact 13 numbers']}) + +    def test_create_success(self): +        serializer = BookSerializer(data={'isbn': '1234567890123'}) +        self.assertTrue(serializer.is_valid()) + +  class MetadataTests(TestCase):      def test_empty(self):          serializer = CommentSerializer()  | 
