Бэкэнд Django не поддерживает абсолютные пути - PullRequest
0 голосов
/ 18 октября 2018

Я работаю Обрезать изображения в приложении Django

, используя это руководство Обрезать изображения в Django

Myform:

class UploadImageForm(forms.ModelForm):
x = forms.FloatField(widget=forms.HiddenInput())
y = forms.FloatField(widget=forms.HiddenInput())
width = forms.FloatField(widget=forms.HiddenInput())
height = forms.FloatField(widget=forms.HiddenInput())
primaryphoto = forms.ImageField(required=False,
                                error_messages={'invalid': _("Image files only")}, widget=forms.FileInput)
class Meta:
    model = User
    fields = ['primaryphoto', 'x', 'y', 'width', 'height',]


def save(self):
    user = super(UploadImageForm, self).save()
    x = self.cleaned_data.get('x')
    y = self.cleaned_data.get('y')
    w = self.cleaned_data.get('width')
    h = self.cleaned_data.get('height')

    image = Image.open(user.primaryphoto)
    cropped_image = image.crop((x, y, w + x, h + y))
    resized_image = cropped_image.resize((200, 200), Image.ANTIALIAS)
    resized_image.save(user.primaryphoto.path)

    return user

myview:

def upload_image(request):
if request.method == 'POST':
    form = UploadImageForm(request.POST, request.FILES, instance=request.user)
    if form.is_valid():
        form.save()
        return redirect('/profile')
else:
    form = UploadImageForm(instance=request.user)
return render(request, 'student/uploadimageform.html', {'form': form})

storage_backend.py:

from storages.backends.s3boto3 import S3Boto3Storage

class MediaStorage(S3Boto3Storage):
    location = 'media'
    file_overwrite = False

Однако, когда я загрузил его для запуска на AWS, я получил сообщение об ошибке backend does not support absolute paths (in reference to primaryphoto.path in the form where the photo is cropped).Мне было интересно, что я должен изменить, чтобы заставить его работать с S3.Я нашел некоторые ресурсы, которые говорят, что смените primaryphoto.path на primaryphoto.name, но у меня это не сработало.Мне было интересно, если у вас есть какие-либо рекомендации для решения этой проблемы?

Здесь изображение загружено в S3 Bucket, но проблема выдает ошибку выше.Пожалуйста, помогите мне кто-нибудь.Заранее спасибо ...

Редактировать ответ:

    def save(self):
    user = super(UploadImageForm, self).save()
    x = self.cleaned_data.get('x')
    y = self.cleaned_data.get('y')
    w = self.cleaned_data.get('width')
    h = self.cleaned_data.get('height')
    try:
        image = Image.open(user.primaryphoto)
        cropped_image = image.crop((x, y, w + x, h + y))
        resized_image = cropped_image.resize((200, 200), Image.ANTIALIAS)
        resized_image.save(user.primaryphoto.path)
    except:
        pass

    return user

Здесь проблема выдает ошибку, но изображение загружается локально и S3 bucket правильно ... для обработки ошибки пути я использую try,кроме блока

1 Ответ

0 голосов
/ 18 октября 2018

Вместо этого попробуйте следующее.

Я не тестирую его, но некоторые объяснения будут хороши: Мы конвертируем изображение в строковый буфер для создания Django InMemoryUploadedFileс обрезанным изображением.В этом случае мы не используем path.Попробуйте и дайте мне знать, что вы сталкиваетесь с любыми другими ошибками.

import os
from io import BytesIO as StringIO # python3
from django.core.files.uploadedfile import InMemoryUploadedFile

def save(self):
    user = super(UploadImageForm, self).save()
    x = self.cleaned_data.get('x')
    y = self.cleaned_data.get('y')
    w = self.cleaned_data.get('width')
    h = self.cleaned_data.get('height')

    image = Image.open(user.primaryphoto)
    cropped_image = image.crop((x, y, w + x, h + y))
    resized_image = cropped_image.resize((200, 200), Image.ANTIALIAS)

    filename = os.path.splitext(resized_image.name)[0] 

    output = StringIO()
    resized_image.save(output, format='JPEG', quality=95)
    output.seek(0) #Change the stream position to the given byte offset.


    new_image = InMemoryUploadedFile(output,'ImageField',\
        "%s.jpg" % filename , 'image/jpeg', output.__sizeof__(), None)

    user.primaryphoto = new_image
    user.save()

    return user
...