mirror of
				https://github.com/encode/django-rest-framework.git
				synced 2025-10-31 07:57:55 +03:00 
			
		
		
		
	Fix failing copy of fields when RegexValidator is used. Closes #1954.
This commit is contained in:
		
							parent
							
								
									26b6180f50
								
							
						
					
					
						commit
						0a5d088287
					
				|  | @ -1,7 +1,7 @@ | ||||||
| from django.conf import settings | from django.conf import settings | ||||||
| from django.core import validators |  | ||||||
| from django.core.exceptions import ObjectDoesNotExist | from django.core.exceptions import ObjectDoesNotExist | ||||||
| from django.core.exceptions import ValidationError as DjangoValidationError | from django.core.exceptions import ValidationError as DjangoValidationError | ||||||
|  | from django.core.validators import RegexValidator | ||||||
| from django.forms import ImageField as DjangoImageField | from django.forms import ImageField as DjangoImageField | ||||||
| from django.utils import six, timezone | from django.utils import six, timezone | ||||||
| from django.utils.datastructures import SortedDict | from django.utils.datastructures import SortedDict | ||||||
|  | @ -392,7 +392,15 @@ class Field(object): | ||||||
|         originally created with, rather than copying the complete state. |         originally created with, rather than copying the complete state. | ||||||
|         """ |         """ | ||||||
|         args = copy.deepcopy(self._args) |         args = copy.deepcopy(self._args) | ||||||
|         kwargs = copy.deepcopy(self._kwargs) |         kwargs = dict(self._kwargs) | ||||||
|  |         # Bit ugly, but we need to special case 'validators' as Django's | ||||||
|  |         # RegexValidator does not support deepcopy. | ||||||
|  |         # We treat validator callables as immutable objects. | ||||||
|  |         # See https://github.com/tomchristie/django-rest-framework/issues/1954 | ||||||
|  |         validators = kwargs.pop('validators', None) | ||||||
|  |         kwargs = copy.deepcopy(kwargs) | ||||||
|  |         if validators is not None: | ||||||
|  |             kwargs['validators'] = validators | ||||||
|         return self.__class__(*args, **kwargs) |         return self.__class__(*args, **kwargs) | ||||||
| 
 | 
 | ||||||
|     def __repr__(self): |     def __repr__(self): | ||||||
|  | @ -531,7 +539,7 @@ class RegexField(CharField): | ||||||
| 
 | 
 | ||||||
|     def __init__(self, regex, **kwargs): |     def __init__(self, regex, **kwargs): | ||||||
|         super(RegexField, self).__init__(**kwargs) |         super(RegexField, self).__init__(**kwargs) | ||||||
|         validator = validators.RegexValidator(regex, message=self.error_messages['invalid']) |         validator = RegexValidator(regex, message=self.error_messages['invalid']) | ||||||
|         self.validators.append(validator) |         self.validators.append(validator) | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  | @ -543,7 +551,7 @@ class SlugField(CharField): | ||||||
|     def __init__(self, **kwargs): |     def __init__(self, **kwargs): | ||||||
|         super(SlugField, self).__init__(**kwargs) |         super(SlugField, self).__init__(**kwargs) | ||||||
|         slug_regex = re.compile(r'^[-a-zA-Z0-9_]+$') |         slug_regex = re.compile(r'^[-a-zA-Z0-9_]+$') | ||||||
|         validator = validators.RegexValidator(slug_regex, message=self.error_messages['invalid']) |         validator = RegexValidator(slug_regex, message=self.error_messages['invalid']) | ||||||
|         self.validators.append(validator) |         self.validators.append(validator) | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -1,9 +1,10 @@ | ||||||
| from __future__ import unicode_literals | from __future__ import unicode_literals | ||||||
| from django.core.validators import MaxValueValidator | from django.core.validators import RegexValidator, MaxValueValidator | ||||||
| from django.db import models | from django.db import models | ||||||
| from django.test import TestCase | from django.test import TestCase | ||||||
| from rest_framework import generics, serializers, status | from rest_framework import generics, serializers, status | ||||||
| from rest_framework.test import APIRequestFactory | from rest_framework.test import APIRequestFactory | ||||||
|  | import re | ||||||
| 
 | 
 | ||||||
| factory = APIRequestFactory() | factory = APIRequestFactory() | ||||||
| 
 | 
 | ||||||
|  | @ -174,3 +175,20 @@ class TestChoiceFieldChoicesValidate(TestCase): | ||||||
|     #         f.to_native(value) |     #         f.to_native(value) | ||||||
|     #     except ValidationError: |     #     except ValidationError: | ||||||
|     #         self.fail("Value %s does not validate" % str(value)) |     #         self.fail("Value %s does not validate" % str(value)) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | class RegexSerializer(serializers.Serializer): | ||||||
|  |     pin = serializers.CharField( | ||||||
|  |         validators=[RegexValidator(regex=re.compile('^[0-9]{4,6}$'), | ||||||
|  |                                    message='A PIN is 4-6 digits')]) | ||||||
|  | 
 | ||||||
|  | expected_repr = """ | ||||||
|  | RegexSerializer(): | ||||||
|  |     pin = CharField(validators=[<django.core.validators.RegexValidator object>]) | ||||||
|  | """.strip() | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | class TestRegexSerializer(TestCase): | ||||||
|  |     def test_regex_repr(self): | ||||||
|  |         serializer_repr = repr(RegexSerializer()) | ||||||
|  |         assert serializer_repr == expected_repr | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue
	
	Block a user