Django migrations和FileSystemStorage取决于设置

2024-06-07 00:59:15 发布

您现在位置:Python中文网/ 问答频道 /正文

在我的Django应用程序中,我对生成的文件使用FileSystemStorage。我这样初始化它:

import os
from urlparse import urljoin

from django.conf import settings
from django.core.files.storage import FileSystemStorage

gen_files_storage = FileSystemStorage(location=os.path.join(settings.MEDIA_ROOT, 'generated/'), base_url=urljoin(settings.MEDIA_URL, 'generated/'))

当我想创建一个新文件时,我使用:

^{pr2}$

那很好。唯一的问题是在Django迁移中,FileSystemStorage的路径是“硬编码”的。因为我在开发(更改)和生产时使用不同的设置,manage.py makemigrations命令通常只因为路径更改而生成迁移,尽管数据库中的所有内容都保持不变。在

我知道有一个使用FileSystemStorage子类的解决方案(见下面我的答案),但是有更好的解决方案吗?在


Tags: 文件djangofromimport路径settingsosstorage
3条回答

解决方案是永远不要在生产上运行makemigrations。在生产服务器上运行migrate,但如果与此问题有关,则忽略有关运行makemigrations的警告。在

考虑一下:makemigrations生成Python代码,因此在生产上运行它与在该服务器上开发是一样的。根据您的服务器设置,无论makemigrations警告如何,您的生产站点可能会正确地提供这些文件。在

有一个解决方案涉及FileSystemStorage的自定义@deconstructible子类:

import os
from urlparse import urljoin

from django.conf import settings
from django.core.files.storage import FileSystemStorage
from django.utils.deconstruct import deconstructible

@deconstructible
class MyFileSystemStorage(FileSystemStorage):
    def __init__(self, subdir):
        self.subdir = subdir
        super(MyFileSystemStorage, self).__init__(location=os.path.join(settings.MEDIA_ROOT, self.subdir), base_url=urljoin(settings.MEDIA_URL, self.subdir))

    def __eq__(self, other):
        return self.subdir == other.subdir

然后我可以像这样初始化存储:

^{pr2}$

这样Django迁移就不会注意到我的设置中的更改。有更好的方法吗?在

我的问题是相关的,但略有不同。字段使用的存储类可以根据设置进行更改:默认本地存储,生产中的远程存储。我实现了一个FileField的子类,它在解构迁移生成字段时忽略了存储kwarg。在

from django.db.models import FileField

class VariableStorageFileField(FileField):
    """
    Disregard the storage kwarg when creating migrations for this field
    """

    def deconstruct(self):
        name, path, args, kwargs = super(VariableStorageFileField, self).deconstruct()
        kwargs.pop('storage', None)
        return name, path, args, kwargs

它可以这样使用:

^{pr2}$

相关问题 更多 >