Repository: encode/django-rest-framework

Issue:
SlugField doesn't accept Unicode
## Steps to reproduce
 
The model has a SlugField with `allow_unicode=True`

```
class Person(models.Model):
    name = models.SlugField(
        allow_unicode=True,
        max_length=155,
        unique=True
    )
```

The serializer is a `ModelSerializers`:
```
class PersonSerializer(serializers.ModelSerializer):
    class Meta:
        model = User
        fields = ('name',  )
```

## Expected behavior

The serializer should accept unicode values just like the field on the model.

## Actual behavior


By passing `علیرضا` as value for `name` field, it fails.
The serializer print out the following error:
```
{'name`: ['Enter a valid "slug" consisting of letters, numbers, underscores or hyphens.']}
```


Discussion:
+1  I'm having this problem now.
The initializer doesn't respect `allow_unicode` at all.
`serializers.SlugField` also adds its non-Unicode-aware `RegexValidator` even if custom `validators` were passed in which is pretty mean. https://github.com/encode/django-rest-framework/blob/master/rest_framework/fields.py#L800
PR welcomed :)

Resolving patch:
diff --git a/rest_framework/fields.py b/rest_framework/fields.py
--- a/rest_framework/fields.py
+++ b/rest_framework/fields.py
@@ -791,13 +791,17 @@ def __init__(self, regex, **kwargs):
 
 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)
 
 


Test patch:
diff --git a/tests/test_api_client.py b/tests/test_api_client.py
--- a/tests/test_api_client.py
+++ b/tests/test_api_client.py
@@ -275,13 +275,13 @@ def test_multipart_encoding(self):
         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 @@ def test_raw_upload(self):
         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
--- 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):
     """