31 | 32 | 'RegexField', 'EmailField', 'FileField', 'ImageField', 'URLField', |
32 | 33 | 'BooleanField', 'NullBooleanField', 'ChoiceField', 'MultipleChoiceField', |
33 | 34 | 'ComboField', 'MultiValueField', 'FloatField', 'DecimalField', |
| 759 | |
| 760 | class FilePathField(ChoiceField): |
| 761 | """A ChoiceField whose choices are files or folders from the filesystem""" |
| 762 | |
| 763 | def __init__(self, path, match=None, recursive=False, required=True, widget=None, label=None, initial=None, help_text=None, *args, **kwargs): |
| 764 | self.path, self.match, self.recursive = path, match, recursive |
| 765 | super(FilePathField, self).__init__(choices=(), required=required, widget=widget, label=label, initial=initial, help_text=help_text, *args, **kwargs) |
| 766 | self.choices = [] |
| 767 | if self.match is not None: |
| 768 | self.match_re = re.compile(self.match) |
| 769 | if recursive: |
| 770 | for root, dirs, files in os.walk(self.path): |
| 771 | for f in files: |
| 772 | if self.match is None or self.match_re.search(f): |
| 773 | f = os.path.join(root, f) |
| 774 | self.choices.append((f, f.replace(self.path, "", 1))) |
| 775 | else: |
| 776 | try: |
| 777 | for f in os.listdir(self.path): |
| 778 | full_file = os.path.join(self.path, f) |
| 779 | if os.path.isfile(full_file) and (self.match is None or self.match_re.search(f)): |
| 780 | self.choices.append((full_file, f)) |
| 781 | except OSError: |
| 782 | pass |
| 783 | self.widget.choices = self.choices |