from django import forms from django.utils.translation import ugettext_lazy as _, ungettext_lazy ATTRIBUTE_PLACEHOLDER = 'placeholder' ATTRIBUTE_ROWS = 'rows' URL_ROWS = 2 class MultipleFileInput(forms.FileInput): """ Input that allows to enter many files at once, utilizing the html5 "multiple" attribute of a file input. """ def value_from_datadict(self, data, files, name): if len(files) == 0: return None else: return files.getlist(name) def render(self, name, value, attrs=None): if not attrs: attrs = dict() attrs['multiple'] = '' return super().render(name, None, attrs=attrs) class MultipleFileField(forms.FileField): """ Field that allows to enter multiple files from one input. """ def to_python(self, data): if not data or len(data) == 0: return None for file in data: super().to_python(file) return data class UrlFileWidget(forms.MultiWidget): """ Widget with a file input and a text input that allows to enter either a file from a local system, or a URL from which the file would be downloaded. """ def __init__(self, *args, **kwargs): widgets = ( MultipleFileInput(attrs={'accept': 'file/*'}), forms.Textarea(attrs={ ATTRIBUTE_PLACEHOLDER: 'http://example.com/image.png', ATTRIBUTE_ROWS: URL_ROWS, }), ) super().__init__(widgets, *args, **kwargs) def decompress(self, value): return [None, None] class UrlFileField(forms.MultiValueField): """ Field with a file input and a text input that allows to enter either a file from a local system, or a URL from which the file would be downloaded. """ widget = UrlFileWidget def __init__(self, *args, **kwargs): fields = ( MultipleFileField(required=False, label=_('File')), forms.CharField(required=False, label=_('File URL')), ) super().__init__( fields=fields, require_all_fields=False, *args, **kwargs) def compress(self, data_list): all_data = [] for data in data_list: if type(data) == list: all_data += data elif type(data) == str and len(data) > 0: file_input = data.replace('\r\n', '\n') url_list = file_input.split('\n') all_data += url_list return all_data