Commit c20a0250 by Aider Ibragimov

add FilePathField, update docs

parent 33c4278e
...@@ -189,6 +189,20 @@ A field that ensures the input is a valid UUID string. The `to_internal_value` m ...@@ -189,6 +189,20 @@ A field that ensures the input is a valid UUID string. The `to_internal_value` m
"de305d54-75b4-431b-adb2-eb6b9e546013" "de305d54-75b4-431b-adb2-eb6b9e546013"
## FilePathField
A field whose choices are limited to the filenames in a certain directory on the filesystem
Corresponds to `django.forms.fields.FilePathField`.
**Signature:** `FilePathField(path, match=None, recursive=False, allow_files=True, allow_folders=False, required=None, **kwargs)`
- `path` - The absolute filesystem path to a directory from which this FilePathField should get its choice.
- `match` - A regular expression, as a string, that FilePathField will use to filter filenames.
- `recursive` - Specifies whether all subdirectories of path should be included. Default is `False`.
- `allow_files` - Specifies whether files in the specified location should be included. Default is `True`. Either this or `allow_folders` must be `True`.
- `allow_folders` - Specifies whether folders in the specified location should be included. Default is `False`. Either this or `allow_files` must be `True`.
--- ---
# Numeric fields # Numeric fields
......
...@@ -3,7 +3,9 @@ from django.conf import settings ...@@ -3,7 +3,9 @@ from django.conf import settings
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.core.validators import RegexValidator
from django.forms import ImageField as DjangoImageField from django.forms import (
ImageField as DjangoImageField, FilePathField as DjangoFilePathField
)
from django.utils import six, timezone from django.utils import six, timezone
from django.utils.dateparse import parse_date, parse_datetime, parse_time from django.utils.dateparse import parse_date, parse_datetime, parse_time
from django.utils.encoding import is_protected_type, smart_text from django.utils.encoding import is_protected_type, smart_text
...@@ -653,6 +655,40 @@ class UUIDField(Field): ...@@ -653,6 +655,40 @@ class UUIDField(Field):
return str(value) return str(value)
class FilePathField(CharField):
default_error_messages = {
'invalid_choice': _('"{input}" is not a valid path choice.')
}
def __init__(self, path, match=None, recursive=False, allow_files=True,
allow_folders=False, required=None, **kwargs):
super(FilePathField, self).__init__(**kwargs)
# create field and get options to avoid code duplication
field = DjangoFilePathField(
path, match=match, recursive=recursive, allow_files=allow_files,
allow_folders=allow_folders, required=required
)
self.choices = OrderedDict(field.choices)
self.choice_strings_to_values = {
six.text_type(key): key for key in self.choices.keys()
}
def to_internal_value(self, data):
if data == '' and self.allow_blank:
return ''
try:
return self.choice_strings_to_values[six.text_type(data)]
except KeyError:
self.fail('invalid_choice', input=data)
def to_representation(self, value):
if value in ('', None):
return value
return self.choice_strings_to_values[six.text_type(value)]
# Number types... # Number types...
class IntegerField(Field): class IntegerField(Field):
......
...@@ -301,7 +301,10 @@ class HTMLFormRenderer(BaseRenderer): ...@@ -301,7 +301,10 @@ class HTMLFormRenderer(BaseRenderer):
}, },
serializers.ListSerializer: { serializers.ListSerializer: {
'base_template': 'list_fieldset.html' 'base_template': 'list_fieldset.html'
} },
serializers.FilePathField: {
'base_template': 'select.html',
},
}) })
def render_field(self, field, parent_style): def render_field(self, field, parent_style):
......
from decimal import Decimal
from django.utils import timezone
from rest_framework import serializers
import datetime import datetime
import os
import uuid
from decimal import Decimal
import django import django
import pytest import pytest
import uuid from django.utils import timezone
from rest_framework import serializers
# Tests for field keyword arguments and core functionality. # Tests for field keyword arguments and core functionality.
...@@ -518,6 +520,24 @@ class TestUUIDField(FieldValues): ...@@ -518,6 +520,24 @@ class TestUUIDField(FieldValues):
field = serializers.UUIDField() field = serializers.UUIDField()
class TestFilePathField(FieldValues):
"""
Valid and invalid values for `FilePathField`
"""
valid_inputs = {
__file__: __file__,
}
invalid_inputs = {
'wrong_path': ['"wrong_path" is not a valid path choice.']
}
outputs = {
}
field = serializers.FilePathField(
path=os.path.abspath(os.path.dirname(__file__))
)
# Number types... # Number types...
class TestIntegerField(FieldValues): class TestIntegerField(FieldValues):
......
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