Fixed #27358 -- Added a system check to prevent FileField's upload_to from starting with a slash.

Thanks Frank Bijlsma for the initial patch.
This commit is contained in:
Henry Dang 2016-11-26 13:23:03 -05:00 committed by Tim Graham
parent b8a815e9df
commit 7cddd8a02e
3 changed files with 42 additions and 0 deletions

View File

@ -240,6 +240,7 @@ class FileField(Field):
def check(self, **kwargs):
errors = super(FileField, self).check(**kwargs)
errors.extend(self._check_primary_key())
errors.extend(self._check_upload_to())
return errors
def _check_primary_key(self):
@ -254,6 +255,20 @@ class FileField(Field):
else:
return []
def _check_upload_to(self):
if isinstance(self.upload_to, six.string_types) and self.upload_to[0] == '/':
return [
checks.Error(
"%s's 'upload_to' argument must be a relative path, not an "
"absolute path." % self.__class__.__name__,
obj=self,
id='fields.E202',
hint='Remove the leading slash.',
)
]
else:
return []
def deconstruct(self):
name, path, args, kwargs = super(FileField, self).deconstruct()
if kwargs.get("max_length") == 100:

View File

@ -189,6 +189,8 @@ File Fields
* **fields.E200**: ``unique`` is not a valid argument for a ``FileField``.
*This check is removed in Django 1.11*.
* **fields.E201**: ``primary_key`` is not a valid argument for a ``FileField``.
* **fields.E202**: ``FileField``s ``upload_to`` argument must be a relative
path, not an absolute path.
* **fields.E210**: Cannot use ``ImageField`` because Pillow is not installed.
Related Fields

View File

@ -455,6 +455,31 @@ class FileFieldTests(SimpleTestCase):
]
self.assertEqual(errors, expected)
def test_upload_to_starts_with_slash(self):
class Model(models.Model):
field = models.FileField(upload_to='/somewhere')
field = Model._meta.get_field('field')
self.assertEqual(field.check(), [
Error(
"FileField's 'upload_to' argument must be a relative path, not "
"an absolute path.",
obj=field,
id='fields.E202',
hint='Remove the leading slash.',
)
])
def test_upload_to_callable_not_checked(self):
def callable(instance, filename):
return '/' + filename
class Model(models.Model):
field = models.FileField(upload_to=callable)
field = Model._meta.get_field('field')
self.assertEqual(field.check(), [])
@isolate_apps('invalid_models_tests')
class FilePathFieldTests(SimpleTestCase):