Ticket #5893: filepath-folders.2.diff
File filepath-folders.2.diff, 10.3 KB (added by , 15 years ago) |
---|
-
django/core/management/validation.py
diff --git a/django/core/management/validation.py b/django/core/management/validation.py index 97164d7..185edd1 100644
a b def get_validation_errors(outfile, app=None): 53 53 e.add(opts, '"%s": To use ImageFields, you need to install the Python Imaging Library. Get it at http://www.pythonware.com/products/pil/ .' % f.name) 54 54 if isinstance(f, models.BooleanField) and getattr(f, 'null', False): 55 55 e.add(opts, '"%s": BooleanFields do not accept null values. Use a NullBooleanField instead.' % f.name) 56 if isinstance(f, models.FilePathField) and not (f.allow_files or f.allow_folders): 57 e.add(opts, '"%s": FilePathFields must have either allow_files or allow_folders set to True.' % f.name) 56 58 if f.choices: 57 59 if isinstance(f.choices, basestring) or not is_iterable(f.choices): 58 60 e.add(opts, '"%s": "choices" should be iterable (e.g., a tuple or list).' % f.name) -
django/db/models/fields/__init__.py
diff --git a/django/db/models/fields/__init__.py b/django/db/models/fields/__init__.py index 05238cf..95cf61a 100644
a b 1 1 import copy 2 2 import datetime 3 import decimal 3 4 import os 4 5 import re 5 6 import time 6 try:7 import decimal8 except ImportError:9 from django.utils import _decimal as decimal # for Python 2.310 7 11 8 from django.db import connection 12 9 from django.db.models import signals … … class EmailField(CharField): 671 668 class FilePathField(Field): 672 669 """File path""" 673 670 674 def __init__(self, verbose_name=None, name=None, path='', match=None, recursive=False, **kwargs): 671 def __init__(self, verbose_name=None, name=None, path='', match=None, 672 recursive=False, allow_files=True, allow_folders=False, **kwargs): 675 673 self.path, self.match, self.recursive = path, match, recursive 674 self.allow_files, self.allow_folders = allow_files, allow_folders 676 675 kwargs['max_length'] = kwargs.get('max_length', 100) 677 676 Field.__init__(self, verbose_name, name, **kwargs) 678 677 … … class FilePathField(Field): 682 681 'match': self.match, 683 682 'recursive': self.recursive, 684 683 'form_class': forms.FilePathField, 684 'allow_files': self.allow_files, 685 'allow_folders': self.allow_folders, 685 686 } 686 687 defaults.update(kwargs) 687 688 return super(FilePathField, self).formfield(**defaults) -
django/forms/fields.py
diff --git a/django/forms/fields.py b/django/forms/fields.py index 0aef355..db6ebd0 100644
a b try: 12 12 from cStringIO import StringIO 13 13 except ImportError: 14 14 from StringIO import StringIO 15 from decimal import Decimal, DecimalException 15 16 16 # Python 2.3 fallbacks17 try:18 from decimal import Decimal, DecimalException19 except ImportError:20 from django.utils._decimal import Decimal, DecimalException21 try:22 set23 except NameError:24 from sets import Set as set25 17 26 18 import django.core.exceptions 27 19 from django.utils.translation import ugettext_lazy as _ … … class MultiValueField(Field): 822 814 raise NotImplementedError('Subclasses must implement this method.') 823 815 824 816 class FilePathField(ChoiceField): 825 def __init__(self, path, match=None, recursive=False, required=True,826 widget=None, label=None, initial=None, help_text=None,827 817 def __init__(self, path, match=None, recursive=False, allow_files=True, 818 allow_folders=False, required=True, widget=Select, label=None, 819 initial=None, help_text=None, *args, **kwargs): 828 820 self.path, self.match, self.recursive = path, match, recursive 821 self.allow_files, self.allow_folders = allow_files, allow_folders 829 822 super(FilePathField, self).__init__(choices=(), required=required, 830 823 widget=widget, label=label, initial=initial, help_text=help_text, 831 824 *args, **kwargs) … … class FilePathField(ChoiceField): 840 833 841 834 if recursive: 842 835 for root, dirs, files in os.walk(self.path): 843 for f in files: 844 if self.match is None or self.match_re.search(f): 845 f = os.path.join(root, f) 846 self.choices.append((f, f.replace(path, "", 1))) 836 if self.allow_files: 837 for f in files: 838 if self.match is None or self.match_re.search(f): 839 f = os.path.join(root, f) 840 self.choices.append((f, f.replace(path, "", 1))) 841 if self.allow_folders: 842 for f in dirs: 843 if self.match is None or self.match_re.search(f): 844 f = os.path.join(root, f) 845 self.choices.append((f, f.replace(path, "", 1))) 847 846 else: 848 847 try: 849 848 for f in os.listdir(self.path): 850 849 full_file = os.path.join(self.path, f) 851 if os.path.isfile(full_file) and (self.match is None or self.match_re.search(f)): 850 if (((self.allow_files and os.path.isfile(full_file)) or 851 (self.allow_folders and os.path.isdir(full_file))) and 852 (self.match is None or self.match_re.search(f))): 852 853 self.choices.append((full_file, f)) 853 854 except OSError: 854 855 pass -
docs/ref/forms/fields.txt
diff --git a/docs/ref/forms/fields.txt b/docs/ref/forms/fields.txt index 4bb6a7c..74be0c6 100644
a b extra arguments; only ``path`` is required: 523 523 A regular expression pattern; only files with names matching this expression 524 524 will be allowed as choices. 525 525 526 .. attribute:: FilePathField.allow_files 527 528 .. versionadded:: 1.2 529 530 Optional. Either ``True`` or ``False``. Default is ``True``. Specifies 531 whether files in the specified location should be included. Either this or 532 :attr:`~FilePathField.allow_folders` must be ``True``. 533 534 .. attribute:: FilePathField.allow_folders 535 536 .. versionadded:: 1.2 537 538 Optional. Either ``True`` or ``False``. Default is ``False``. Specifies 539 whether folders in the specified location should be included. Either this 540 or :attr:`~FilePathField.allow_files` must be ``True``. 541 526 542 ``FloatField`` 527 543 ~~~~~~~~~~~~~~ 528 544 -
docs/ref/models/fields.txt
diff --git a/docs/ref/models/fields.txt b/docs/ref/models/fields.txt index 0cb5be4..fba9e07 100644
a b directory on the filesystem. Has three special arguments, of which the first is 571 571 Optional. Either ``True`` or ``False``. Default is ``False``. Specifies 572 572 whether all subdirectories of :attr:`~FilePathField.path` should be included 573 573 574 .. attribute:: FilePathField.allow_files 575 576 .. versionadded:: 1.2 577 578 Optional. Either ``True`` or ``False``. Default is ``True``. Specifies 579 whether files in the specified location should be included. Either this or 580 :attr:`~FilePathField.allow_folders` must be ``True``. 581 582 .. attribute:: FilePathField.allow_folders 583 584 .. versionadded:: 1.2 585 586 Optional. Either ``True`` or ``False``. Default is ``False``. Specifies 587 whether folders in the specified location should be included. Either this 588 or :attr:`~FilePathField.allow_files` must be ``True``. 589 590 574 591 Of course, these arguments can be used together. 575 592 576 593 The one potential gotcha is that :attr:`~FilePathField.match` applies to the -
tests/regressiontests/forms/fields.py
diff --git a/tests/regressiontests/forms/fields.py b/tests/regressiontests/forms/fields.py index c9736d3..c67e68f 100644
a b Each Field's __init__() takes at least these parameters: 24 24 Other than that, the Field subclasses have class-specific options for 25 25 __init__(). For example, CharField has a max_length option. 26 26 """ 27 27 28 import datetime 28 29 import time 29 30 import re 30 31 import os 31 32 33 from decimal import Decimal 32 34 from unittest import TestCase 33 35 34 36 from django.core.files.uploadedfile import SimpleUploadedFile 35 37 from django.forms import * 36 38 from django.forms.widgets import RadioFieldRenderer 37 39 38 try:39 from decimal import Decimal40 except ImportError:41 from django.utils._decimal import Decimal42 43 40 44 41 def fix_os_paths(x): 45 42 if isinstance(x, basestring): … … class FieldsTests(TestCase): 815 812 for exp, got in zip(expected, fix_os_paths(f.choices)): 816 813 self.assertEqual(exp[1], got[1]) 817 814 assert got[0].endswith(exp[0]) 815 816 def test_filepathfield_folders(self): 817 path = forms.__file__ 818 path = os.path.dirname(path) + '/' 819 f = FilePathField(path=path, allow_folders=True, allow_files=False) 820 f.choices.sort() 821 expected = [ 822 ('/django/forms/extras', 'extras'), 823 ] 824 for exp, got in zip(expected, fix_os_paths(f.choices)): 825 self.assertEqual(exp[1], got[1]) 826 self.assert_(got[0].endswith(exp[0])) 827 828 f = FilePathField(path=path, allow_folders=True, allow_files=True) 829 f.choices.sort() 830 expected = [ 831 ('/django/forms/__init__.py', '__init__.py'), 832 ('/django/forms/__init__.pyc', '__init__.pyc'), 833 ('/django/forms/extras', 'extras'), 834 ('/django/forms/fields.py', 'fields.py'), 835 ('/django/forms/fields.pyc', 'fields.pyc'), 836 ('/django/forms/forms.py', 'forms.py'), 837 ('/django/forms/forms.pyc', 'forms.pyc'), 838 ('/django/forms/formsets.py', 'formsets.py'), 839 ('/django/forms/formsets.pyc', 'formsets.pyc'), 840 ('/django/forms/models.py', 'models.py'), 841 ('/django/forms/models.pyc', 'models.pyc'), 842 ('/django/forms/util.py', 'util.py'), 843 ('/django/forms/util.pyc', 'util.pyc'), 844 ('/django/forms/widgets.py', 'widgets.py'), 845 ('/django/forms/widgets.pyc', 'widgets.pyc') 846 ] 847 for exp, got in zip(expected, fix_os_paths(f.choices)): 848 self.assertEqual(exp[1], got[1]) 849 self.assert_(got[0].endswith(exp[0])) 850 818 851 819 852 # SplitDateTimeField ########################################################## 820 853