Ticket #5893: filepath-folders.3.diff
File filepath-folders.3.diff, 11.0 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 29de8c7..e5aa74a 100644
a b class CharField(Field): 567 567 568 568 def get_prep_value(self, value): 569 569 return self.to_python(value) 570 570 571 571 def formfield(self, **kwargs): 572 572 # Passing max_length to forms.CharField means that the value's length 573 573 # will be validated twice. This is considered acceptable since we want … … class EmailField(CharField): 813 813 class FilePathField(Field): 814 814 description = _("File path") 815 815 816 def __init__(self, verbose_name=None, name=None, path='', match=None, recursive=False, **kwargs): 816 def __init__(self, verbose_name=None, name=None, path='', match=None, 817 recursive=False, allow_files=True, allow_folders=False, **kwargs): 817 818 self.path, self.match, self.recursive = path, match, recursive 819 self.allow_files, self.allow_folders = allow_files, allow_folders 818 820 kwargs['max_length'] = kwargs.get('max_length', 100) 819 821 Field.__init__(self, verbose_name, name, **kwargs) 820 822 … … class FilePathField(Field): 824 826 'match': self.match, 825 827 'recursive': self.recursive, 826 828 'form_class': forms.FilePathField, 829 'allow_files': self.allow_files, 830 'allow_folders': self.allow_folders, 827 831 } 828 832 defaults.update(kwargs) 829 833 return super(FilePathField, self).formfield(**defaults) … … class XMLField(TextField): 1113 1117 def __init__(self, verbose_name=None, name=None, schema_path=None, **kwargs): 1114 1118 self.schema_path = schema_path 1115 1119 Field.__init__(self, verbose_name, name, **kwargs) 1116 -
django/forms/fields.py
diff --git a/django/forms/fields.py b/django/forms/fields.py index 2e6eb82..55d4096 100644
a b try: 14 14 except ImportError: 15 15 from StringIO import StringIO 16 16 17 17 18 from django.core.exceptions import ValidationError 18 19 from django.core import validators 19 import django.utils.copycompat as copy20 from django.utils import copycompat as copy 20 21 from django.utils.translation import ugettext_lazy as _ 21 22 from django.utils.encoding import smart_unicode, smart_str 22 23 from django.utils.formats import get_format … … class ChoiceField(Field): 579 580 580 581 def __init__(self, choices=(), required=True, widget=None, label=None, 581 582 initial=None, help_text=None, *args, **kwargs): 582 super(ChoiceField, self).__init__(required=required, widget=widget, label=label, 583 super(ChoiceField, self).__init__(required=required, widget=widget, label=label, 583 584 initial=initial, help_text=help_text, *args, **kwargs) 584 585 self.choices = choices 585 586 … … class MultiValueField(Field): 779 780 raise NotImplementedError('Subclasses must implement this method.') 780 781 781 782 class FilePathField(ChoiceField): 782 def __init__(self, path, match=None, recursive=False, required=True,783 widget=None, label=None, initial=None, help_text=None,784 783 def __init__(self, path, match=None, recursive=False, allow_files=True, 784 allow_folders=False, required=True, widget=Select, label=None, 785 initial=None, help_text=None, *args, **kwargs): 785 786 self.path, self.match, self.recursive = path, match, recursive 787 self.allow_files, self.allow_folders = allow_files, allow_folders 786 788 super(FilePathField, self).__init__(choices=(), required=required, 787 789 widget=widget, label=label, initial=initial, help_text=help_text, 788 790 *args, **kwargs) … … class FilePathField(ChoiceField): 797 799 798 800 if recursive: 799 801 for root, dirs, files in os.walk(self.path): 800 for f in files: 801 if self.match is None or self.match_re.search(f): 802 f = os.path.join(root, f) 803 self.choices.append((f, f.replace(path, "", 1))) 802 if self.allow_files: 803 for f in files: 804 if self.match is None or self.match_re.search(f): 805 f = os.path.join(root, f) 806 self.choices.append((f, f.replace(path, "", 1))) 807 if self.allow_folders: 808 for f in dirs: 809 if self.match is None or self.match_re.search(f): 810 f = os.path.join(root, f) 811 self.choices.append((f, f.replace(path, "", 1))) 804 812 else: 805 813 try: 806 814 for f in os.listdir(self.path): 807 815 full_file = os.path.join(self.path, f) 808 if os.path.isfile(full_file) and (self.match is None or self.match_re.search(f)): 816 if (((self.allow_files and os.path.isfile(full_file)) or 817 (self.allow_folders and os.path.isdir(full_file))) and 818 (self.match is None or self.match_re.search(f))): 809 819 self.choices.append((full_file, f)) 810 820 except OSError: 811 821 pass -
docs/ref/forms/fields.txt
diff --git a/docs/ref/forms/fields.txt b/docs/ref/forms/fields.txt index 6440d2e..b91eebb 100644
a b extra arguments; only ``path`` is required: 534 534 A regular expression pattern; only files with names matching this expression 535 535 will be allowed as choices. 536 536 537 .. attribute:: FilePathField.allow_files 538 539 .. versionadded:: 1.2 540 541 Optional. Either ``True`` or ``False``. Default is ``True``. Specifies 542 whether files in the specified location should be included. Either this or 543 :attr:`~FilePathField.allow_folders` must be ``True``. 544 545 .. attribute:: FilePathField.allow_folders 546 547 .. versionadded:: 1.2 548 549 Optional. Either ``True`` or ``False``. Default is ``False``. Specifies 550 whether folders in the specified location should be included. Either this 551 or :attr:`~FilePathField.allow_files` must be ``True``. 552 537 553 ``FloatField`` 538 554 ~~~~~~~~~~~~~~ 539 555 -
docs/ref/models/fields.txt
diff --git a/docs/ref/models/fields.txt b/docs/ref/models/fields.txt index 6a98afb..1e68a3d 100644
a b directory on the filesystem. Has three special arguments, of which the first is 605 605 Optional. Either ``True`` or ``False``. Default is ``False``. Specifies 606 606 whether all subdirectories of :attr:`~FilePathField.path` should be included 607 607 608 .. attribute:: FilePathField.allow_files 609 610 .. versionadded:: 1.2 611 612 Optional. Either ``True`` or ``False``. Default is ``True``. Specifies 613 whether files in the specified location should be included. Either this or 614 :attr:`~FilePathField.allow_folders` must be ``True``. 615 616 .. attribute:: FilePathField.allow_folders 617 618 .. versionadded:: 1.2 619 620 Optional. Either ``True`` or ``False``. Default is ``False``. Specifies 621 whether folders in the specified location should be included. Either this 622 or :attr:`~FilePathField.allow_files` must be ``True``. 623 624 608 625 Of course, these arguments can be used together. 609 626 610 627 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 8733090..081e886 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): 819 816 for exp, got in zip(expected, fix_os_paths(f.choices)): 820 817 self.assertEqual(exp[1], got[1]) 821 818 assert got[0].endswith(exp[0]) 819 820 def test_filepathfield_folders(self): 821 path = forms.__file__ 822 path = os.path.dirname(path) + '/' 823 f = FilePathField(path=path, allow_folders=True, allow_files=False) 824 f.choices.sort() 825 expected = [ 826 ('/django/forms/extras', 'extras'), 827 ] 828 for exp, got in zip(expected, fix_os_paths(f.choices)): 829 self.assertEqual(exp[1], got[1]) 830 self.assert_(got[0].endswith(exp[0])) 831 832 f = FilePathField(path=path, allow_folders=True, allow_files=True) 833 f.choices.sort() 834 expected = [ 835 ('/django/forms/__init__.py', '__init__.py'), 836 ('/django/forms/__init__.pyc', '__init__.pyc'), 837 ('/django/forms/extras', 'extras'), 838 ('/django/forms/fields.py', 'fields.py'), 839 ('/django/forms/fields.pyc', 'fields.pyc'), 840 ('/django/forms/forms.py', 'forms.py'), 841 ('/django/forms/forms.pyc', 'forms.pyc'), 842 ('/django/forms/formsets.py', 'formsets.py'), 843 ('/django/forms/formsets.pyc', 'formsets.pyc'), 844 ('/django/forms/models.py', 'models.py'), 845 ('/django/forms/models.pyc', 'models.pyc'), 846 ('/django/forms/util.py', 'util.py'), 847 ('/django/forms/util.pyc', 'util.pyc'), 848 ('/django/forms/widgets.py', 'widgets.py'), 849 ('/django/forms/widgets.pyc', 'widgets.pyc') 850 ] 851 for exp, got in zip(expected, fix_os_paths(f.choices)): 852 self.assertEqual(exp[1], got[1]) 853 self.assert_(got[0].endswith(exp[0])) 854 822 855 823 856 # SplitDateTimeField ########################################################## 824 857