#22337 closed Bug (fixed)
makemigrations not working when Field takes FileSystemStorage parameter
| Reported by: | nliberg | Owned by: | nobody | 
|---|---|---|---|
| Component: | Migrations | Version: | 1.7-beta-1 | 
| Severity: | Release blocker | Keywords: | FileSystemStorage, migrations | 
| Cc: | Triage Stage: | Accepted | |
| Has patch: | yes | Needs documentation: | no | 
| Needs tests: | no | Patch needs improvement: | no | 
| Easy pickings: | no | UI/UX: | no | 
Description
FileSystemStorage is not serializable. Because of this running ./manage.py makemigrations for an app that contains fields that use such storage results in an exception:
ValueError: Cannot serialize: <django.core.files.storage.FileSystemStorage object at 0x109c02310>
Background:
When manage.py makemigrations is run on a new app the deconstruct method is invoked for all fields. According to the django documentation every value in the deconstructed kwargs dictionary "should itself be serializable". However, this is not the case when one passes a FileSystemStorage object as storage parameter to the FileField constructor. The deconstruct method of the FileFIeld class adds the FileSystemStorage storage object to kwargs without it being serializable.
Fix:
I attach a patch that adds a deconstruct method to the django.core.files.storage.FileSystemStorage class.
Reproducing
The problem can be reproduced by starting a new app using the following models.py file and running ./manage.py makemigrations <appname>
from django.db import models from django.core.files.storage import FileSystemStorage class MyModel(models.Model): myfile = models.FileField('File', upload_to='myfiles', storage=FileSystemStorage(location='/tmp'))
Attachments (2)
Change History (15)
comment:1 by , 12 years ago
| Severity: | Normal → Release blocker | 
|---|---|
| Triage Stage: | Unreviewed → Accepted | 
comment:2 by , 12 years ago
| Needs tests: | set | 
|---|---|
| Patch needs improvement: | set | 
by , 12 years ago
| Attachment: | FileSystemStorage_deconstruct.patch added | 
|---|
Add deconstruct method to django.core.files.storage.FileSystemStorage
by , 12 years ago
| Attachment: | FileSystemStorage_deconstruct_tests.patch added | 
|---|
Tests for FileSystemStorage decode method
comment:3 by , 12 years ago
I modified the original patch slightly. The decode method now avoids adding items to kwargs where the value is the default value. Furthermore I added some test code to tests/file_storage/tests.py in the second patch.
comment:4 by , 12 years ago
| Easy pickings: | unset | 
|---|---|
| Needs tests: | unset | 
| Patch needs improvement: | unset | 
comment:5 by , 12 years ago
I propose that the storage should be omitted from FileField.deconstruct(). It's an optional kwarg and it has no impact on the database. Changes in custom storages could potentially break past migrations. In south the various states of each model were stored as dicts of strings so that changes in python code could not break schema. I cover this in more detail in several related tickets: #22373, #22351, and #22436.
comment:7 by , 12 years ago
+1 on the excluding storage from FileField.deconstruct as chriscauley proposes. This affects migrations with custom storages such as S3BotoStorage from django-storages. Unless there is an expectation that all storage backends will implement deconstruct (to no benefit from what I can tell, as it does not actually affect the migration), it seems like an unnecessary burden on updating projects.
comment:8 by , 11 years ago
Why not using ®deconstructible from django.utils.deconstruct? That should work with most subclasses of storage without extra efforts from their authors'.
Regarding skipping storage in deconstruct(), that means FileField wouldn't work in RunPython operation, I'd rather keep the fake ORM as capable as possible.
comment:9 by , 11 years ago
Yes, we have to keep all parameters on fields, even if they're not database-affecting; the RunPython method still sees those fields and uses them from Python.
I'll fix this now using @deconstructible, as Loic is correct that it's safe to use here.
comment:10 by , 11 years ago
| Resolution: | → fixed | 
|---|---|
| Status: | new → closed | 
The patch looks sensible and it does seem to fix the issue but it needs some tests too.
Thanks.