Fixed #589 -- Added FilePathField. It's available as an ORM field and as a standalone field in django.core.formfields. Thanks, jay@skabber.com
git-svn-id: http://code.djangoproject.com/svn/django/trunk@846 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
parent
9fdacc7a66
commit
5f9fe6d403
|
@ -143,6 +143,7 @@ DATA_TYPES = {
|
||||||
'DateTimeField': 'datetime',
|
'DateTimeField': 'datetime',
|
||||||
'EmailField': 'varchar(75)',
|
'EmailField': 'varchar(75)',
|
||||||
'FileField': 'varchar(100)',
|
'FileField': 'varchar(100)',
|
||||||
|
'FilePathField': 'varchar(100)',
|
||||||
'FloatField': 'numeric(%(max_digits)s, %(decimal_places)s)',
|
'FloatField': 'numeric(%(max_digits)s, %(decimal_places)s)',
|
||||||
'ImageField': 'varchar(100)',
|
'ImageField': 'varchar(100)',
|
||||||
'IntegerField': 'integer',
|
'IntegerField': 'integer',
|
||||||
|
|
|
@ -154,6 +154,7 @@ DATA_TYPES = {
|
||||||
'DateTimeField': 'timestamp with time zone',
|
'DateTimeField': 'timestamp with time zone',
|
||||||
'EmailField': 'varchar(75)',
|
'EmailField': 'varchar(75)',
|
||||||
'FileField': 'varchar(100)',
|
'FileField': 'varchar(100)',
|
||||||
|
'FilePathField': 'varchar(100)',
|
||||||
'FloatField': 'numeric(%(max_digits)s, %(decimal_places)s)',
|
'FloatField': 'numeric(%(max_digits)s, %(decimal_places)s)',
|
||||||
'ImageField': 'varchar(100)',
|
'ImageField': 'varchar(100)',
|
||||||
'IntegerField': 'integer',
|
'IntegerField': 'integer',
|
||||||
|
|
|
@ -154,6 +154,7 @@ DATA_TYPES = {
|
||||||
'DateTimeField': 'datetime',
|
'DateTimeField': 'datetime',
|
||||||
'EmailField': 'varchar(75)',
|
'EmailField': 'varchar(75)',
|
||||||
'FileField': 'varchar(100)',
|
'FileField': 'varchar(100)',
|
||||||
|
'FilePathField': 'varchar(100)',
|
||||||
'FloatField': 'numeric(%(max_digits)s, %(decimal_places)s)',
|
'FloatField': 'numeric(%(max_digits)s, %(decimal_places)s)',
|
||||||
'ImageField': 'varchar(100)',
|
'ImageField': 'varchar(100)',
|
||||||
'IntegerField': 'integer',
|
'IntegerField': 'integer',
|
||||||
|
|
|
@ -707,6 +707,29 @@ class IPAddressField(TextField):
|
||||||
# MISCELLANEOUS #
|
# MISCELLANEOUS #
|
||||||
####################
|
####################
|
||||||
|
|
||||||
|
class FilePathField(SelectField):
|
||||||
|
"A SelectField whose choices are the files in a given directory."
|
||||||
|
def __init__(self, field_name, path, match=None, recursive=False, is_required=False, validator_list=[]):
|
||||||
|
import os
|
||||||
|
if match is not None:
|
||||||
|
import re
|
||||||
|
match_re = re.compile(match)
|
||||||
|
choices = []
|
||||||
|
if recursive:
|
||||||
|
for root, dirs, files in os.walk(path):
|
||||||
|
for f in files:
|
||||||
|
if match is None or match_re.search(f):
|
||||||
|
choices.append((os.path.join(path, f), f))
|
||||||
|
else:
|
||||||
|
try:
|
||||||
|
for f in os.listdir(path):
|
||||||
|
full_file = os.path.join(path, f)
|
||||||
|
if os.path.isfile(full_file) and (match is None or match_re.search(f)):
|
||||||
|
choices.append((full_file, f))
|
||||||
|
except OSError:
|
||||||
|
pass
|
||||||
|
SelectField.__init__(self, field_name, choices, 1, is_required, validator_list)
|
||||||
|
|
||||||
class PhoneNumberField(TextField):
|
class PhoneNumberField(TextField):
|
||||||
"A convenience FormField for validating phone numbers (e.g. '630-555-1234')"
|
"A convenience FormField for validating phone numbers (e.g. '630-555-1234')"
|
||||||
def __init__(self, field_name, is_required=False, validator_list=[]):
|
def __init__(self, field_name, is_required=False, validator_list=[]):
|
||||||
|
|
|
@ -427,6 +427,14 @@ class FileField(Field):
|
||||||
f = os.path.join(self.get_directory_name(), get_valid_filename(os.path.basename(filename)))
|
f = os.path.join(self.get_directory_name(), get_valid_filename(os.path.basename(filename)))
|
||||||
return os.path.normpath(f)
|
return os.path.normpath(f)
|
||||||
|
|
||||||
|
class FilePathField(Field):
|
||||||
|
def __init__(self, verbose_name=None, name=None, path='', match=None, recursive=False, **kwargs):
|
||||||
|
self.path, self.match, self.recursive = path, match, recursive
|
||||||
|
Field.__init__(self, verbose_name, name, **kwargs)
|
||||||
|
|
||||||
|
def get_manipulator_field_objs(self):
|
||||||
|
return [curry(formfields.FilePathField, path=self.path, match=self.match, recursive=self.recursive)]
|
||||||
|
|
||||||
class FloatField(Field):
|
class FloatField(Field):
|
||||||
empty_strings_allowed = False
|
empty_strings_allowed = False
|
||||||
def __init__(self, verbose_name=None, name=None, max_digits=None, decimal_places=None, **kwargs):
|
def __init__(self, verbose_name=None, name=None, max_digits=None, decimal_places=None, **kwargs):
|
||||||
|
|
|
@ -272,6 +272,40 @@ Here are all available field types:
|
||||||
|
|
||||||
.. _`strftime formatting`: http://docs.python.org/lib/module-time.html#l2h-1941
|
.. _`strftime formatting`: http://docs.python.org/lib/module-time.html#l2h-1941
|
||||||
|
|
||||||
|
``FilePathField``
|
||||||
|
A field whose choices are limited to the filenames in a certain directory
|
||||||
|
on the filesystem. Has three special arguments, of which the first is
|
||||||
|
required:
|
||||||
|
|
||||||
|
====================== ===================================================
|
||||||
|
Argument Description
|
||||||
|
====================== ===================================================
|
||||||
|
``path`` Required. The absolute filesystem path to a
|
||||||
|
directory from which this ``FilePathField`` should
|
||||||
|
get its choices. Example: ``"/home/images"``.
|
||||||
|
|
||||||
|
``match`` Optional. A regular expression, as a string, that
|
||||||
|
``FilePathField`` will use to filter filenames.
|
||||||
|
Note that the regex will be applied to the
|
||||||
|
base filename, not the full path. Example:
|
||||||
|
``"foo.*\.txt^"``, which will match a file called
|
||||||
|
``foo23.txt`` but not ``bar.txt`` or ``foo23.gif``.
|
||||||
|
|
||||||
|
``recursive`` Optional. Either ``True`` or ``False``. Default is
|
||||||
|
``False``. Specifies whether all subdirectories of
|
||||||
|
``path`` should be included.
|
||||||
|
|
||||||
|
Of course, these arguments can be used together.
|
||||||
|
|
||||||
|
The one potential gotcha is that ``match`` applies to the base filename,
|
||||||
|
not the full path. So, this example::
|
||||||
|
|
||||||
|
FilePathField(path="/home/images", match="foo.*", recursive=True)
|
||||||
|
|
||||||
|
...will match ``/home/images/foo.gif`` but not ``/home/images/foo/bar.gif``
|
||||||
|
because the ``match`` applies to the base filename (``foo.gif`` and
|
||||||
|
``bar.gif``).
|
||||||
|
|
||||||
``FloatField``
|
``FloatField``
|
||||||
A floating-point number. Has two **required** arguments:
|
A floating-point number. Has two **required** arguments:
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue