Commit 0a5d0882 by Tom Christie

Fix failing copy of fields when RegexValidator is used. Closes #1954.

parent 26b6180f
from django.conf import settings
from django.core import validators
from django.core.exceptions import ObjectDoesNotExist
from django.core.exceptions import ValidationError as DjangoValidationError
from django.core.validators import RegexValidator
from django.forms import ImageField as DjangoImageField
from django.utils import six, timezone
from django.utils.datastructures import SortedDict
......@@ -392,7 +392,15 @@ class Field(object):
originally created with, rather than copying the complete state.
"""
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)
def __repr__(self):
......@@ -531,7 +539,7 @@ class RegexField(CharField):
def __init__(self, regex, **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)
......@@ -543,7 +551,7 @@ class SlugField(CharField):
def __init__(self, **kwargs):
super(SlugField, self).__init__(**kwargs)
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)
......
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.test import TestCase
from rest_framework import generics, serializers, status
from rest_framework.test import APIRequestFactory
import re
factory = APIRequestFactory()
......@@ -174,3 +175,20 @@ class TestChoiceFieldChoicesValidate(TestCase):
# f.to_native(value)
# except ValidationError:
# 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
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment