Loading AUTHORS +1 −0 Original line number Diff line number Diff line Loading @@ -146,6 +146,7 @@ answer newbie questions, and generally made Django that much better: Jorge Gajon <gajon@gajon.org> gandalf@owca.info Marc Garcia <marc.garcia@accopensys.com> Alex Gaynor <alex.gaynor@gmail.com> Andy Gayton <andy-django@thecablelounge.com> Baishampayan Ghose Dimitris Glezos <dimitris@glezos.com> Loading django/db/models/fields/__init__.py +10 −0 Original line number Diff line number Diff line Loading @@ -843,6 +843,16 @@ class FilePathField(Field): kwargs['max_length'] = kwargs.get('max_length', 100) Field.__init__(self, verbose_name, name, **kwargs) def formfield(self, **kwargs): defaults = { 'path': self.path, 'match': self.match, 'recursive': self.recursive, 'form_class': forms.FilePathField, } defaults.update(kwargs) return super(FilePathField, self).formfield(**defaults) def get_manipulator_field_objs(self): return [curry(oldforms.FilePathField, path=self.path, match=self.match, recursive=self.recursive)] Loading django/newforms/fields.py +29 −1 Original line number Diff line number Diff line Loading @@ -4,6 +4,7 @@ Field classes. import copy import datetime import os import re import time # Python 2.3 fallbacks Loading Loading @@ -31,7 +32,7 @@ __all__ = ( 'RegexField', 'EmailField', 'FileField', 'ImageField', 'URLField', 'BooleanField', 'NullBooleanField', 'ChoiceField', 'MultipleChoiceField', 'ComboField', 'MultiValueField', 'FloatField', 'DecimalField', 'SplitDateTimeField', 'IPAddressField', 'SplitDateTimeField', 'IPAddressField', 'FilePathField', ) # These values, if given to to_python(), will trigger the self.required check. Loading Loading @@ -718,6 +719,33 @@ class MultiValueField(Field): """ raise NotImplementedError('Subclasses must implement this method.') class FilePathField(ChoiceField): def __init__(self, path, match=None, recursive=False, required=True, widget=Select, label=None, initial=None, help_text=None, *args, **kwargs): self.path, self.match, self.recursive = path, match, recursive super(FilePathField, self).__init__(choices=(), required=required, widget=widget, label=label, initial=initial, help_text=help_text, *args, **kwargs) self.choices = [] if self.match is not None: self.match_re = re.compile(self.match) if recursive: for root, dirs, files in os.walk(self.path): for f in files: if self.match is None or self.match_re.search(f): f = os.path.join(root, f) self.choices.append((f, f.replace(path, "", 1))) else: try: for f in os.listdir(self.path): full_file = os.path.join(self.path, f) if os.path.isfile(full_file) and (self.match is None or self.match_re.search(f)): self.choices.append((full_file, f)) except OSError: pass self.widget.choices = self.choices class SplitDateTimeField(MultiValueField): default_error_messages = { 'invalid_date': _(u'Enter a valid date.'), Loading docs/newforms.txt +37 −4 Original line number Diff line number Diff line Loading @@ -1333,13 +1333,14 @@ given length. An ``UploadedFile`` object has two attributes: ====================== ===================================================== Argument Description ====================== ===================================================== ====================== ==================================================== Attribute Description ====================== ==================================================== ``filename`` The name of the file, provided by the uploading client. ``content`` The array of bytes comprising the file content. ====================== ===================================================== ====================== ==================================================== The string representation of an ``UploadedFile`` is the same as the filename attribute. Loading @@ -1349,6 +1350,38 @@ When you use a ``FileField`` on a form, you must also remember to .. _`bind the file data to the form`: `Binding uploaded files to a form`_ ``FilePathField`` ~~~~~~~~~~~~~~~~~ **New in Django development version** * Default widget: ``Select`` * Empty value: ``None`` * Normalizes to: A unicode object * Validates that the selected choice exists in the list of choices. * Error message keys: ``required``, ``invalid_choice`` The field allows choosing from files inside a certain directory. It takes three extra arguments: ============== ========== =============================================== Argument Required? Description ============== ========== =============================================== ``path`` Yes The absolute path to the directory whose contents you want listed. This directory must exist. ``recursive`` No If ``False`` (the default) only the direct contents of ``path`` will be offered as choices. If ``True``, the directory will be descended into recursively and all descendants will be listed as choices. ``match`` No A regular expression pattern; only files with names matching this expression will be allowed as choices. ============== ========== =============================================== ``ImageField`` ~~~~~~~~~~~~~~ Loading tests/regressiontests/forms/fields.py +27 −0 Original line number Diff line number Diff line Loading @@ -1133,6 +1133,33 @@ u'' >>> f.clean(None) u'' # FilePathField ############################################################### >>> import os >>> from django import newforms as forms >>> path = forms.__file__ >>> path = os.path.dirname(path) + '/' >>> path '.../django/newforms/' >>> f = forms.FilePathField(path=path) >>> f.choices.sort() >>> f.choices [('.../django/newforms/__init__.py', '__init__.py'), ('.../django/newforms/__init__.pyc', '__init__.pyc'), ('.../django/newforms/fields.py', 'fields.py'), ('.../django/newforms/fields.pyc', 'fields.pyc'), ('.../django/newforms/forms.py', 'forms.py'), ('.../django/newforms/forms.pyc', 'forms.pyc'), ('.../django/newforms/models.py', 'models.py'), ('.../django/newforms/models.pyc', 'models.pyc'), ('.../django/newforms/util.py', 'util.py'), ('.../django/newforms/util.pyc', 'util.pyc'), ('.../django/newforms/widgets.py', 'widgets.py'), ('.../django/newforms/widgets.pyc', 'widgets.pyc')] >>> f.clean('fields.py') Traceback (most recent call last): ... ValidationError: [u'Select a valid choice. That choice is not one of the available choices.'] >>> f.clean(path + 'fields.py') u'.../django/newforms/fields.py' >>> f = forms.FilePathField(path=path, match='^.*?\.py$') >>> f.choices.sort() >>> f.choices [('.../django/newforms/__init__.py', '__init__.py'), ('.../django/newforms/fields.py', 'fields.py'), ('.../django/newforms/forms.py', 'forms.py'), ('.../django/newforms/models.py', 'models.py'), ('.../django/newforms/util.py', 'util.py'), ('.../django/newforms/widgets.py', 'widgets.py')] >>> f = forms.FilePathField(path=path, recursive=True, match='^.*?\.py$') >>> f.choices.sort() >>> f.choices [('.../django/newforms/__init__.py', '__init__.py'), ('.../django/newforms/extras/__init__.py', 'extras/__init__.py'), ('.../django/newforms/extras/widgets.py', 'extras/widgets.py'), ('.../django/newforms/fields.py', 'fields.py'), ('.../django/newforms/forms.py', 'forms.py'), ('.../django/newforms/models.py', 'models.py'), ('.../django/newforms/util.py', 'util.py'), ('.../django/newforms/widgets.py', 'widgets.py')] # SplitDateTimeField ########################################################## >>> f = SplitDateTimeField() Loading Loading
AUTHORS +1 −0 Original line number Diff line number Diff line Loading @@ -146,6 +146,7 @@ answer newbie questions, and generally made Django that much better: Jorge Gajon <gajon@gajon.org> gandalf@owca.info Marc Garcia <marc.garcia@accopensys.com> Alex Gaynor <alex.gaynor@gmail.com> Andy Gayton <andy-django@thecablelounge.com> Baishampayan Ghose Dimitris Glezos <dimitris@glezos.com> Loading
django/db/models/fields/__init__.py +10 −0 Original line number Diff line number Diff line Loading @@ -843,6 +843,16 @@ class FilePathField(Field): kwargs['max_length'] = kwargs.get('max_length', 100) Field.__init__(self, verbose_name, name, **kwargs) def formfield(self, **kwargs): defaults = { 'path': self.path, 'match': self.match, 'recursive': self.recursive, 'form_class': forms.FilePathField, } defaults.update(kwargs) return super(FilePathField, self).formfield(**defaults) def get_manipulator_field_objs(self): return [curry(oldforms.FilePathField, path=self.path, match=self.match, recursive=self.recursive)] Loading
django/newforms/fields.py +29 −1 Original line number Diff line number Diff line Loading @@ -4,6 +4,7 @@ Field classes. import copy import datetime import os import re import time # Python 2.3 fallbacks Loading Loading @@ -31,7 +32,7 @@ __all__ = ( 'RegexField', 'EmailField', 'FileField', 'ImageField', 'URLField', 'BooleanField', 'NullBooleanField', 'ChoiceField', 'MultipleChoiceField', 'ComboField', 'MultiValueField', 'FloatField', 'DecimalField', 'SplitDateTimeField', 'IPAddressField', 'SplitDateTimeField', 'IPAddressField', 'FilePathField', ) # These values, if given to to_python(), will trigger the self.required check. Loading Loading @@ -718,6 +719,33 @@ class MultiValueField(Field): """ raise NotImplementedError('Subclasses must implement this method.') class FilePathField(ChoiceField): def __init__(self, path, match=None, recursive=False, required=True, widget=Select, label=None, initial=None, help_text=None, *args, **kwargs): self.path, self.match, self.recursive = path, match, recursive super(FilePathField, self).__init__(choices=(), required=required, widget=widget, label=label, initial=initial, help_text=help_text, *args, **kwargs) self.choices = [] if self.match is not None: self.match_re = re.compile(self.match) if recursive: for root, dirs, files in os.walk(self.path): for f in files: if self.match is None or self.match_re.search(f): f = os.path.join(root, f) self.choices.append((f, f.replace(path, "", 1))) else: try: for f in os.listdir(self.path): full_file = os.path.join(self.path, f) if os.path.isfile(full_file) and (self.match is None or self.match_re.search(f)): self.choices.append((full_file, f)) except OSError: pass self.widget.choices = self.choices class SplitDateTimeField(MultiValueField): default_error_messages = { 'invalid_date': _(u'Enter a valid date.'), Loading
docs/newforms.txt +37 −4 Original line number Diff line number Diff line Loading @@ -1333,13 +1333,14 @@ given length. An ``UploadedFile`` object has two attributes: ====================== ===================================================== Argument Description ====================== ===================================================== ====================== ==================================================== Attribute Description ====================== ==================================================== ``filename`` The name of the file, provided by the uploading client. ``content`` The array of bytes comprising the file content. ====================== ===================================================== ====================== ==================================================== The string representation of an ``UploadedFile`` is the same as the filename attribute. Loading @@ -1349,6 +1350,38 @@ When you use a ``FileField`` on a form, you must also remember to .. _`bind the file data to the form`: `Binding uploaded files to a form`_ ``FilePathField`` ~~~~~~~~~~~~~~~~~ **New in Django development version** * Default widget: ``Select`` * Empty value: ``None`` * Normalizes to: A unicode object * Validates that the selected choice exists in the list of choices. * Error message keys: ``required``, ``invalid_choice`` The field allows choosing from files inside a certain directory. It takes three extra arguments: ============== ========== =============================================== Argument Required? Description ============== ========== =============================================== ``path`` Yes The absolute path to the directory whose contents you want listed. This directory must exist. ``recursive`` No If ``False`` (the default) only the direct contents of ``path`` will be offered as choices. If ``True``, the directory will be descended into recursively and all descendants will be listed as choices. ``match`` No A regular expression pattern; only files with names matching this expression will be allowed as choices. ============== ========== =============================================== ``ImageField`` ~~~~~~~~~~~~~~ Loading
tests/regressiontests/forms/fields.py +27 −0 Original line number Diff line number Diff line Loading @@ -1133,6 +1133,33 @@ u'' >>> f.clean(None) u'' # FilePathField ############################################################### >>> import os >>> from django import newforms as forms >>> path = forms.__file__ >>> path = os.path.dirname(path) + '/' >>> path '.../django/newforms/' >>> f = forms.FilePathField(path=path) >>> f.choices.sort() >>> f.choices [('.../django/newforms/__init__.py', '__init__.py'), ('.../django/newforms/__init__.pyc', '__init__.pyc'), ('.../django/newforms/fields.py', 'fields.py'), ('.../django/newforms/fields.pyc', 'fields.pyc'), ('.../django/newforms/forms.py', 'forms.py'), ('.../django/newforms/forms.pyc', 'forms.pyc'), ('.../django/newforms/models.py', 'models.py'), ('.../django/newforms/models.pyc', 'models.pyc'), ('.../django/newforms/util.py', 'util.py'), ('.../django/newforms/util.pyc', 'util.pyc'), ('.../django/newforms/widgets.py', 'widgets.py'), ('.../django/newforms/widgets.pyc', 'widgets.pyc')] >>> f.clean('fields.py') Traceback (most recent call last): ... ValidationError: [u'Select a valid choice. That choice is not one of the available choices.'] >>> f.clean(path + 'fields.py') u'.../django/newforms/fields.py' >>> f = forms.FilePathField(path=path, match='^.*?\.py$') >>> f.choices.sort() >>> f.choices [('.../django/newforms/__init__.py', '__init__.py'), ('.../django/newforms/fields.py', 'fields.py'), ('.../django/newforms/forms.py', 'forms.py'), ('.../django/newforms/models.py', 'models.py'), ('.../django/newforms/util.py', 'util.py'), ('.../django/newforms/widgets.py', 'widgets.py')] >>> f = forms.FilePathField(path=path, recursive=True, match='^.*?\.py$') >>> f.choices.sort() >>> f.choices [('.../django/newforms/__init__.py', '__init__.py'), ('.../django/newforms/extras/__init__.py', 'extras/__init__.py'), ('.../django/newforms/extras/widgets.py', 'extras/widgets.py'), ('.../django/newforms/fields.py', 'fields.py'), ('.../django/newforms/forms.py', 'forms.py'), ('.../django/newforms/models.py', 'models.py'), ('.../django/newforms/util.py', 'util.py'), ('.../django/newforms/widgets.py', 'widgets.py')] # SplitDateTimeField ########################################################## >>> f = SplitDateTimeField() Loading