Django,boto,S3和easy_thumbnails不能在生产环境中工作

时间:2013-03-17 18:19:43

标签: django amazon-s3 boto

我正在使用Django,带有S3(boto)的django-storage与简单缩略图相结合。在我的本地计算机上,一切都按预期工作:如果缩略图不存在,它将被创建并上传到S3并保存在简易缩略图数据库表中。但问题是,当我将代码推送到我的生产服务器时,它不起作用,简单缩略图输出一个空图像SRC。

我已经注意到,当我在本地计算机上创建缩略图时,easy-thumbnail路径使用反斜杠,而我的Linux服务器需要转发斜杠。如果我更改数据库中的斜杠,缩略图会显示在我的Linux机器上,但它仍然无法在Linux(生产)机器上生成缩略图。

简单的django-storages测试失败:

>>> import django
>>> from django.core.files.storage import default_storage
>>> file = default_storage.open('storage_test', 'w')

输出: django.core.exceptions.ImproperlyConfigured:请求设置DEFAULT_FILE_STORAGE,但未配置设置。您必须先定义环境变量DJANGO_SETTINGS_MODULE或在访问设置之前调用settings.configure()。

如果我这样做:

>>> from base.settings import staging
>>> from django.conf import settings
>>> settings.configure(staging)

这样可行(我有一个settings目录,其中包含4个设置文件:base.py,staging.py,development.py和production.py)

似乎在我的生产服务器上,配置文件未正确加载(但网站的其余部分工作正常)。如果我将THUMBNAIL_DEBUG = True添加到我的设置文件中,但是简单缩略图的调试仍然无效(它可以在我的本地计算机上运行)。

有什么问题?我已经调试了10多个小时了。

3 个答案:

答案 0 :(得分:1)

尝试重构您的设置以使用更面向对象的结构。 [来自Disqus的David Cramer概述了一个很好的例子:

http://justcramer.com/2011/01/13/settings-in-django/

您可以将任何特定于服务器的设置放在local_settings.py文件中,并且可以在您的存储库中将精简版本存储为example_local_settings.py

如果您有许多特定于登台或审阅服务器的设置,但仍然可以使用单独的设置文件,但您不希望在代码仓库中存储完整的数据库凭据,因此您必须自定义{ {1}}无论如何。您可以通过在local_settings.py顶部添加导入来定义要包含的设置:

local_settings.py

然后,您可以将from project.conf.settings.dev import * 设置为始终指向同一位置。这将是而不是调用DJANGO_SETTINGS_MODULE,如Django文档中所述:

https://docs.djangoproject.com/en/dev/topics/settings/#either-configure-or-django-settings-module-is-required

这样,您就知道您的生产服务器上的设置肯定会被导入,因为settings.configure()始终是导入的。

答案 1 :(得分:0)

首先尝试使用:

python manage.py shell --settings=settings/staging

使用正确的设置文件加载shell,然后尝试调试

答案 2 :(得分:0)

出于某种原因,模板语言中的S3和简单的缩略图似乎并没有相互融合......某些路径问题可能在某些时候可能得到解决。

我的解决方案(阅读:解决方法)是将缩略图生成移动到图像字段itseld内的模型中,例如:

avatar = ThumbnailerImageField(upload_to = avatar_file_name, resize_source=dict(size=(125, 125), crop="smart"), blank = True)

为了完整起见:

def avatar_file_name(instance, filename):
    path = "%s/avatar.%s" % (str(instance.user.username), filename.split('.')[1])
    if os.path.exists(settings.MEDIA_ROOT + path):
        os.remove(settings.MEDIA_ROOT + path)   
    return path