Skip to content

Commit

Permalink
Fixes #28184 - Add ability to pass a callable as the storage param to…
Browse files Browse the repository at this point in the history
… FileField, and add test

Signed-off-by: miigotu <miigotu@gmail.com>
  • Loading branch information
miigotu committed May 8, 2017
1 parent d842ada commit 8350a16
Show file tree
Hide file tree
Showing 3 changed files with 32 additions and 2 deletions.
4 changes: 4 additions & 0 deletions django/db/models/fields/files.py
Expand Up @@ -225,6 +225,10 @@ def __init__(self, verbose_name=None, name=None, upload_to='', storage=None, **k
self._primary_key_set_explicitly = 'primary_key' in kwargs

self.storage = storage or default_storage

if callable(self.storage):
self.storage = self.storage()

self.upload_to = upload_to

kwargs['max_length'] = kwargs.get('max_length', 100)
Expand Down
15 changes: 14 additions & 1 deletion tests/file_storage/models.py
Expand Up @@ -20,6 +20,15 @@ def get_valid_name(self, name):

temp_storage_location = tempfile.mkdtemp()
temp_storage = FileSystemStorage(location=temp_storage_location)
temp_valid_name_storage = CustomValidNameStorage(location=temp_storage_location)

use_valid_name_storage = False


def callable_temp_storage():
if use_valid_name_storage:
return temp_valid_name_storage
return temp_storage


class Storage(models.Model):
Expand All @@ -35,9 +44,13 @@ def random_upload_to(self, filename):
custom = models.FileField(storage=temp_storage, upload_to=custom_upload_to)
random = models.FileField(storage=temp_storage, upload_to=random_upload_to)
custom_valid_name = models.FileField(
storage=CustomValidNameStorage(location=temp_storage_location),
storage=temp_valid_name_storage,
upload_to=random_upload_to,
)
callable_storage = models.FileField(
storage=callable_temp_storage,
upload_to=custom_upload_to,
)
default = models.FileField(storage=temp_storage, upload_to='tests', default='tests/default.txt')
empty = models.FileField(storage=temp_storage)
limited_length = models.FileField(storage=temp_storage, upload_to='tests', max_length=20)
Expand Down
15 changes: 14 additions & 1 deletion tests/file_storage/tests.py
Expand Up @@ -24,7 +24,11 @@
from django.urls import NoReverseMatch, reverse_lazy
from django.utils import timezone

from .models import Storage, temp_storage, temp_storage_location
from . import models
from .models import (
Storage, temp_storage, temp_storage_location, temp_valid_name_storage,
)


FILE_SUFFIX_REGEX = '[A-Za-z0-9]{7}'

Expand Down Expand Up @@ -801,6 +805,15 @@ def test_stringio(self):
with temp_storage.open('tests/stringio') as f:
self.assertEqual(f.read(), b'content')

def test_callable_storage_param(self):
models.use_valid_name_storage = False
obj1 = Storage.objects.create()
self.assertIs(obj1.callable_storage.storage, temp_storage)

models.use_valid_name_storage = True
obj2 = Storage.objects.create()
self.assertIs(obj2.callable_storage.storage, temp_valid_name_storage)


# Tests for a race condition on file saving (#4948).
# This is written in such a way that it'll always pass on platforms
Expand Down

0 comments on commit 8350a16

Please sign in to comment.