Django 仅在生产环境中使用私有 S3 存储 [英] Django use private S3 storage only in production environment

查看:37
本文介绍了Django 仅在生产环境中使用私有 S3 存储的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已将 django REST API 设置为在调试模式下使用本地存储,在生产环境中使用 S3 存储.这适用于公共文件,因为我像这样覆盖了 DEFAULT_FILE_STORAGE :

I have set up my django REST API to use local storage when in DEBUG mode and S3 storage when in production environment. This works well for public files, because I override the DEFAULT_FILE_STORAGE like so:

if IS_DEBUG:
    DEFAULT_FILE_STORAGE = 'api.storage_backends.PublicMediaStorage'

和每个 FileField 自动使用它.现在我想以同样的方式使用私有 S3 存储,但因为我必须明确定义存储 (FileField(storage=PrivateMediaStorage())),所以总是使用 S3 存储.

and every FileField uses it automatically. Now I want to use private S3 storage the same way, but because I have to define the storage explicitly (FileField(storage=PrivateMediaStorage())), the S3 storage is always used.

如何在 DEBUG 模式下使用本地存储而不是 S3 存储?

How can I use the local storage instead of S3 storage when in DEBUG mode?

PS:我已经考虑过将模型更改为使用带有或不带有显式存储的 FileField,具体取决于调试模式.这并没有完全解决我的问题,因为我的迁移是在 DEBUG 模式下创建的,因此始终包含没有私有存储类的模型.

PS: I have already thought about changing the model to either use a FileField with or without an explicit storage depending on the DEBUG mode. This did not fully solve my problem, because my migrations are created in DEBUG mode and thus always contain the model without the private storage class.

更新:我正在寻找一种解决方案,它可以在两种环境中共享相同的迁移,并且仅在运行时延迟实例化实际存储类.就像 django 已经处理了 DEFAULT_FILE_STORAGE 一样.

UPDATE: I am looking for a solution that can share the same migrations in both environments and only during runtime lazily instantiates the actual storageclass. Just like django handles the DEFAULT_FILE_STORAGE already.

推荐答案

这听起来像是一个棘手的部分是在一个项目中同时拥有公共私有媒体存储.

It sounds like the tricky part here is having both public and private media storage in a single project.

以下示例假设您使用的是 django storages,但该技术应该可行无论如何.

The example below assumes you are using django storages, but the technique should work regardless.

通过扩展 S3BotoStorage 类定义私有存储.

Define a private storage by extending the S3BotoStorage class.

如果使用 S3,最好将 privatepublic 存储在不同的 S3 存储桶中.此自定义存储允许您通过设置指定此参数.

If using S3, it is probably prudent to store private and public public in different S3 buckets. This custom storage allows you to specify this parameter via settings.

# yourapp.custom_storage.py

from django.conf import settings
from django.core.files.storage import get_storage_class
from storages.backends.s3boto import S3BotoStorage

class S3PrivateStorage(S3BotoStorage):
    """
    Optional   
    """
    default_acl = "private"               # this does the trick

    def __init__(self):
        super(S3PrivateStorage, self).__init__()
        self.bucket_name = settings.S3_PRIVATE_STORAGE_BUCKET_NAME


# important
private_storage_class = get_storage_class(settings.PRIVATE_FILE_STORAGE)

private_storage = private_storage_class() # instantiate the storage

重要的部分是这个文件的最后两行——它声明了 private_storage 用于你的 FileField:

The important part is the last 2 lines of this file - it declares private_storage for use in your FileField:

from yourappp.custom_storage import private_storage
...
class YourModel(Model):

    the_file = models.FileField(
                   upload_to=..., 
                   storage=private_storage)
...

最后,在你的设置文件中,应该做这样的事情.

Finally, in your setting file, something like this should do.

# settings.py

if DEBUG:
    # In debug mode, store everything on the filestystem
    DEFAULT_FILE_STORAGE = 'django.files.storage.FileSystemStorage'
    PRIVATE_FILE_STORAGE = 'django.files.storage.FileSystemStorage'
else:
    # In production store public things using S3BotoStorage and private things
    # in a custom storage
    DEFAULT_FILE_STORAGE = 'storages.backends.s3boto.S3BotoStorage'
    PRIVATE_FILE_STORAGE = 'yourapp.custom_storage.S3PrivateStorage'

作为最后一条不请自来的建议:将存储设置与调试模式分离并允许在环境变量中指定上述所有参数通常很有用.在某些时候,您可能希望使用类似生产的存储配置在调试模式下运行您的应用.

As a last piece of unsolicited advice: it is often useful to decouple the storage settings from DEBUG mode and allow all of the parameters above to be specified in environment variables. It is likely that at some point you will want to run your app in debug mode using a production-like storage configuration.

这篇关于Django 仅在生产环境中使用私有 S3 存储的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆