我在实施此处建议的解决方案时遇到问题: PIL thumbnail is rotating my image?
我的情况略有不同,因为我正在使用用户上传的文件。这是我的观点:
from PIL import Image, ExifTags
def add_work_image(request, work_id=None):
image = WorkImage()
image.owner = request.user.profile
image.sort_index = int(request.POST.get('image_order')[0])
source_image = request.FILES.get('image_file')
try:
opened_image = Image.open(source_image)
if hasattr(opened_image, '_getexif'): # only present in JPEGs
for orientation in ExifTags.TAGS.keys():
if ExifTags.TAGS[orientation]=='Orientation':
break
e = opened_image._getexif() # returns None if no EXIF data
if e is not None:
exif=dict(e.items())
orientation = exif[orientation]
print("***** orientation")
print(orientation)
if orientation == 3:
opened_image = opened_image.transpose(Image.ROTATE_180)
elif orientation == 6:
opened_image = opened_image.transpose(Image.ROTATE_270)
elif orientation == 8:
opened_image = opened_image.transpose(Image.ROTATE_90)
new_image_io = BytesIO()
opened_image.save(new_image_io, format='JPEG')
image.image = opened_image
except Exception as e:
print str(e)
image.image = source_image
if work_id:
work = get_object_or_404(Work, pk=work_id)
image.work = work
image.save()
return JsonResponse({
'image_src': image.get_absolute_url(size='work_image'),
'image_id': image.pk})
我不熟悉Django / Python如何处理上传的文件。我在这里缺少什么?
更新了更清晰:
以下是模型:
from django_images.models import Image
class WorkImage(Image):
@classmethod
def get_orphan_images_for_profile(cls, profile, limit=4):
return WorkImage.objects.filter(
work__isnull = True,
owner__pk = profile.pk
).order_by('sort_index', '-created_at').all()[:limit]
work = models.ForeignKey(
Work,
related_name = 'images',
null = True,
on_delete=models.CASCADE
)
owner = models.ForeignKey(
UserProfile)
sort_index = models.IntegerField()
该模型正在使用此django-images。以前,调用image.image = request.FILES.get('image_file')
工作得很好。
我看到的错误:
(原始)
AttributeError: _committed
File "django/core/handlers/base.py", line 149, in get_response
response = self.process_exception_by_middleware(e, request)
File "django/core/handlers/base.py", line 147, in get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "django/contrib/auth/decorators.py", line 23, in _wrapped_view
return view_func(request, *args, **kwargs)
File "django/views/decorators/http.py", line 42, in inner
return func(request, *args, **kwargs)
File "availableworks/utils.py", line 35, in wrapper
return f(request, *args, **kwargs)
File "availableworks/utils.py", line 58, in wrapper
return f(request, *args, **kwargs)
File "availableworks/account/views/works.py", line 78, in add_work_image
image.save()
File "django/db/models/base.py", line 700, in save
force_update=force_update, update_fields=update_fields)
File "django/db/models/base.py", line 727, in save_base
self._save_parents(cls, using, update_fields)
File "django/db/models/base.py", line 752, in _save_parents
self._save_table(cls=parent, using=using, update_fields=update_fields)
File "django/db/models/base.py", line 812, in _save_table
result = self._do_insert(cls._base_manager, using, fields, update_pk, raw)
File "django/db/models/base.py", line 851, in _do_insert
using=using, raw=raw)
File "django/db/models/manager.py", line 122, in manager_method
return getattr(self.get_queryset(), name)(*args, **kwargs)
File "django/db/models/query.py", line 1039, in _insert
return query.get_compiler(using=using).execute_sql(return_id)
File "django/db/models/sql/compiler.py", line 1059, in execute_sql
for sql, params in self.as_sql():
File "django/db/models/sql/compiler.py", line 1019, in as_sql
for obj in self.query.objs
File "django/db/models/sql/compiler.py", line 968, in pre_save_val
return field.pre_save(obj, add=True)
File "django/db/models/fields/files.py", line 309, in pre_save
if file and not file._committed:
File "PIL/Image.py", line 628, in __getattr__
raise AttributeError(name)
(通过Sentry:)