希望有人可以帮忙解决这个问题。谢谢你看看!
我对django和编程都很新,所以请耐心等待。我正在构建一个具有头像ImageField的自定义配置文件应用程序。我在开发中将其全部设置为调整大小并正确定位图像。在heroku上将它推向生产并且必须设置aws s3来提供媒体服务。
我使用Image.open(self.avatar.path)使用我的头像的save方法出错。 最终工作的解决方案是here。但是,更改了模型保存方法后,我尝试在本地上传时出现以下错误。必须有一个比生产与开发的多种保存方法更好的解决方案。但我似乎无法找到解决这两种情况的任何信息。谢谢!
[22/Mar/2016 17:33:24] "GET /profiles/you/ HTTP/1.1" 200 6735
Internal Server Error: /profiles/you/
Traceback (most recent call last):
File "/home/vagrant/virtualenvs/venv_philabucks/lib/python3.4/site-packages/django/core/handlers/base.py", line 149, in get_response
response = self.process_exception_by_middleware(e, request)
File "/home/vagrant/virtualenvs/venv_philabucks/lib/python3.4/site-packages/django/core/handlers/base.py", line 147, in get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/home/vagrant/virtualenvs/venv_philabucks/lib/python3.4/site-packages/django/views/generic/base.py", line 68, in view
return self.dispatch(request, *args, **kwargs)
File "/home/vagrant/virtualenvs/venv_philabucks/lib/python3.4/site-packages/django/views/generic/base.py", line 88, in dispatch
return handler(request, *args, **kwargs)
File "/vagrant/projects/philabucks/profiles/views.py", line 29, in post
form.save()
File "/vagrant/projects/philabucks/profiles/forms.py", line 30, in save
user.save()
File "/vagrant/projects/philabucks/profiles/models.py", line 108, in save
image.save(fh, format)
File "/home/vagrant/virtualenvs/venv_philabucks/lib/python3.4/site-packages/PIL/Image.py", line 1675, in save
save_handler(self, fp, filename)
File "/home/vagrant/virtualenvs/venv_philabucks/lib/python3.4/site-packages/PIL/PngImagePlugin.py", line 690, in _save
fp.write(_MAGIC)
TypeError: must be str, not bytes
[22/Mar/2016 17:33:45] "POST /profiles/you/ HTTP/1.1" 500 92102
以下是我的个人资料模型的相关部分
from django.db import models
from django.contrib.auth.models import BaseUserManager, AbstractBaseUser
from PIL import Image, ExifTags
from PIL.ImageOps import fit
from django.core.files.storage import default_storage as storage
avatar = models.ImageField(upload_to='images/', null=True, blank=True)
def save(self, **kwargs):
super(Profile, self).save()
if self.avatar:
image = Image.open(storage.open(self.avatar.name))
try:
for orientation in ExifTags.TAGS.keys():
if ExifTags.TAGS[orientation]=='Orientation':
break
exif=dict(image._getexif().items())
if exif[orientation] == 3:
image=image.rotate(180, expand=True)
elif exif[orientation] == 6:
image=image.rotate(270, expand=True)
elif exif[orientation] == 8:
image=image.rotate(90, expand=True)
except (AttributeError, KeyError, IndexError):
# cases: image don't have getexif
pass
image = fit(image, (200, 200), Image.ANTIALIAS)
fh = storage.open(self.avatar.name, "w")
format = 'png' # You need to set the correct image format here
image.save(fh, format)
fh.close()
以下是settings / production.py
中的s3设置INSTALLED_APPS += ['storages',]
AWS_QUERYSTRING_AUTH = False
AWS_ACCESS_KEY_ID = os.environ['AWS_ACCESS_KEY_ID']
AWS_SECRET_ACCESS_KEY = os.environ['AWS_SECRET_ACCESS_KEY']
AWS_STORAGE_BUCKET_NAME = os.environ['S3_BUCKET_NAME']
MEDIA_URL = 'http://%s.s3.amazonaws.com/your-folder/' % AWS_STORAGE_BUCKET_NAME
DEFAULT_FILE_STORAGE = "storages.backends.s3boto.S3BotoStorage"
AWS_AUTO_CREATE_BUCKET = True
AWS_HEADERS = {
"Cache-Control": "public, max-age=86400",
}
AWS_S3_FILE_OVERWRITE = False
AWS_S3_SECURE_URLS = True
AWS_REDUCED_REDUNDANCY = False
AWS_IS_GZIPPED = False
这是来自settings / local.py的媒体存储:
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
MEDIA_URL = '/media/'
答案 0 :(得分:0)
我通过更改此行来实现此目的:
fh = storage.open(self.avatar.name, "w")
到这个
fh = storage.open(self.avatar.name, "wb")
找到this非常有用的答案后。我还不确定为什么它在heroku中工作但不在本地工作但是" wb"以二进制打开它,使它在两种情况下都能正常工作。