[1.5.x] Fixed #19525 -- Reverted dcd4383107
and 05d333ba3b
.
Refs #9893, #18515.
Thanks Russell for the report.
Backport of db278c3
from master.
This commit is contained in:
parent
fbc06eef1a
commit
3cb87ec605
|
@ -3,7 +3,6 @@ import os
|
||||||
|
|
||||||
from django import forms
|
from django import forms
|
||||||
from django.db.models.fields import Field
|
from django.db.models.fields import Field
|
||||||
from django.core.exceptions import ValidationError
|
|
||||||
from django.core.files.base import File
|
from django.core.files.base import File
|
||||||
from django.core.files.storage import default_storage
|
from django.core.files.storage import default_storage
|
||||||
from django.core.files.images import ImageFile
|
from django.core.files.images import ImageFile
|
||||||
|
@ -207,10 +206,6 @@ class FileDescriptor(object):
|
||||||
|
|
||||||
class FileField(Field):
|
class FileField(Field):
|
||||||
|
|
||||||
default_error_messages = {
|
|
||||||
'max_length': _('Filename is %(extra)d characters too long.')
|
|
||||||
}
|
|
||||||
|
|
||||||
# The class to wrap instance attributes in. Accessing the file object off
|
# The class to wrap instance attributes in. Accessing the file object off
|
||||||
# the instance will always return an instance of attr_class.
|
# the instance will always return an instance of attr_class.
|
||||||
attr_class = FieldFile
|
attr_class = FieldFile
|
||||||
|
@ -233,25 +228,6 @@ class FileField(Field):
|
||||||
kwargs['max_length'] = kwargs.get('max_length', 100)
|
kwargs['max_length'] = kwargs.get('max_length', 100)
|
||||||
super(FileField, self).__init__(verbose_name, name, **kwargs)
|
super(FileField, self).__init__(verbose_name, name, **kwargs)
|
||||||
|
|
||||||
def validate(self, value, model_instance):
|
|
||||||
"""
|
|
||||||
Validates that the generated file name still fits within max_length.
|
|
||||||
"""
|
|
||||||
# The generated file name stored in the database is generally longer
|
|
||||||
# than the uploaded file name. Using the length of generated name in
|
|
||||||
# the error message would be confusing. However, in the common case
|
|
||||||
# (ie. upload_to='path/to/upload/dir'), the length of the generated
|
|
||||||
# name equals the length of the uploaded name plus a constant. Thus
|
|
||||||
# we can tell the user how much shorter the name should be (roughly).
|
|
||||||
if value and value._committed:
|
|
||||||
filename = value.name
|
|
||||||
else:
|
|
||||||
filename = self.generate_filename(model_instance, value.name)
|
|
||||||
length = len(filename)
|
|
||||||
if self.max_length and length > self.max_length:
|
|
||||||
error_values = {'extra': length - self.max_length}
|
|
||||||
raise ValidationError(self.error_messages['max_length'] % error_values)
|
|
||||||
|
|
||||||
def get_internal_type(self):
|
def get_internal_type(self):
|
||||||
return "FileField"
|
return "FileField"
|
||||||
|
|
||||||
|
|
|
@ -26,5 +26,5 @@ class Storage(models.Model):
|
||||||
|
|
||||||
normal = models.FileField(storage=temp_storage, upload_to='tests')
|
normal = models.FileField(storage=temp_storage, upload_to='tests')
|
||||||
custom = models.FileField(storage=temp_storage, upload_to=custom_upload_to)
|
custom = models.FileField(storage=temp_storage, upload_to=custom_upload_to)
|
||||||
random = models.FileField(storage=temp_storage, upload_to=random_upload_to, max_length=16)
|
random = models.FileField(storage=temp_storage, upload_to=random_upload_to)
|
||||||
default = models.FileField(storage=temp_storage, upload_to='tests', default='tests/default.txt')
|
default = models.FileField(storage=temp_storage, upload_to='tests', default='tests/default.txt')
|
||||||
|
|
|
@ -5,7 +5,6 @@ import shutil
|
||||||
import tempfile
|
import tempfile
|
||||||
|
|
||||||
from django.core.cache import cache
|
from django.core.cache import cache
|
||||||
from django.core.exceptions import ValidationError
|
|
||||||
from django.core.files import File
|
from django.core.files import File
|
||||||
from django.core.files.base import ContentFile
|
from django.core.files.base import ContentFile
|
||||||
from django.core.files.uploadedfile import SimpleUploadedFile
|
from django.core.files.uploadedfile import SimpleUploadedFile
|
||||||
|
@ -103,24 +102,6 @@ class FileStorageTests(TestCase):
|
||||||
obj4.random.save("random_file", ContentFile("random content"))
|
obj4.random.save("random_file", ContentFile("random content"))
|
||||||
self.assertTrue(obj4.random.name.endswith("/random_file"))
|
self.assertTrue(obj4.random.name.endswith("/random_file"))
|
||||||
|
|
||||||
def test_max_length(self):
|
|
||||||
"""
|
|
||||||
Test that FileField validates the length of the generated file name
|
|
||||||
that will be stored in the database. Regression for #9893.
|
|
||||||
"""
|
|
||||||
# upload_to = 'unused', so file names are saved as '456/xxxxx'.
|
|
||||||
# max_length = 16, so names longer than 12 characters are rejected.
|
|
||||||
s1 = Storage(random=SimpleUploadedFile(12 * 'x', b"content"))
|
|
||||||
s1.full_clean()
|
|
||||||
with self.assertRaises(ValidationError):
|
|
||||||
Storage(random=SimpleUploadedFile(13 * 'x', b"content")).full_clean()
|
|
||||||
|
|
||||||
# Ticket #18515: validation for an already saved file should not check
|
|
||||||
# against a regenerated file name (and potentially raise a ValidationError
|
|
||||||
# if max_length is exceeded
|
|
||||||
s1.save()
|
|
||||||
s1.full_clean()
|
|
||||||
|
|
||||||
|
|
||||||
class FileTests(unittest.TestCase):
|
class FileTests(unittest.TestCase):
|
||||||
def test_context_manager(self):
|
def test_context_manager(self):
|
||||||
|
|
Loading…
Reference in New Issue