diff --git a/rest_framework/fields.py b/rest_framework/fields.py index 41d6105ca..769f11466 100644 --- a/rest_framework/fields.py +++ b/rest_framework/fields.py @@ -791,13 +791,17 @@ class RegexField(CharField): class SlugField(CharField): default_error_messages = { - 'invalid': _('Enter a valid "slug" consisting of letters, numbers, underscores or hyphens.') + 'invalid': _('Enter a valid "slug" consisting of letters, numbers, underscores or hyphens.'), + 'invalid_unicode': _('Enter a valid "slug" consisting of Unicode letters, numbers, underscores, or hyphens.') } - def __init__(self, **kwargs): + def __init__(self, allow_unicode=False, **kwargs): super(SlugField, self).__init__(**kwargs) - slug_regex = re.compile(r'^[-a-zA-Z0-9_]+$') - validator = RegexValidator(slug_regex, message=self.error_messages['invalid']) + self.allow_unicode = allow_unicode + if self.allow_unicode: + validator = RegexValidator(re.compile(r'^[-\w]+\Z', re.UNICODE), message=self.error_messages['invalid_unicode']) + else: + validator = RegexValidator(re.compile(r'^[-a-zA-Z0-9_]+$'), message=self.error_messages['invalid']) self.validators.append(validator) diff --git a/tests/test_api_client.py b/tests/test_api_client.py index 60c918701..e4354ec60 100644 --- a/tests/test_api_client.py +++ b/tests/test_api_client.py @@ -275,13 +275,13 @@ class APIClientTests(APITestCase): client = CoreAPIClient() schema = client.get('http://api.example.com/') - temp = tempfile.NamedTemporaryFile() - temp.write(b'example file content') - temp.flush() + with tempfile.NamedTemporaryFile() as temp: + temp.write(b'example file content') + temp.flush() + temp.seek(0) - with open(temp.name, 'rb') as upload: - name = os.path.basename(upload.name) - data = client.action(schema, ['encoding', 'multipart'], params={'example': upload}) + name = os.path.basename(temp.name) + data = client.action(schema, ['encoding', 'multipart'], params={'example': temp}) expected = { 'method': 'POST', @@ -407,13 +407,13 @@ class APIClientTests(APITestCase): client = CoreAPIClient() schema = client.get('http://api.example.com/') - temp = tempfile.NamedTemporaryFile() - temp.write(b'example file content') - temp.flush() + with tempfile.NamedTemporaryFile(delete=False) as temp: + temp.write(b'example file content') + temp.flush() + temp.seek(0) - with open(temp.name, 'rb') as upload: - name = os.path.basename(upload.name) - data = client.action(schema, ['encoding', 'raw_upload'], params={'example': upload}) + name = os.path.basename(temp.name) + data = client.action(schema, ['encoding', 'raw_upload'], params={'example': temp}) expected = { 'method': 'POST', diff --git a/tests/test_fields.py b/tests/test_fields.py index 968c41d3f..bb3d349b4 100644 --- a/tests/test_fields.py +++ b/tests/test_fields.py @@ -704,6 +704,17 @@ class TestSlugField(FieldValues): outputs = {} field = serializers.SlugField() + def test_allow_unicode_true(self): + field = serializers.SlugField(allow_unicode=True) + + validation_error = False + try: + field.run_validation(u'slug-99-\u0420') + except serializers.ValidationError: + validation_error = True + + assert not validation_error + class TestURLField(FieldValues): """