У меня определены некоторые модели, и я пытаюсь написать метод create_image()
. Я не хочу, чтобы изображения были больше, чем 960x720 (или 720x960). Я пытался следовать этому уроку среди других, но я не совсем понял его правильно. Пожалуйста, посмотрите на мой код и скажите, что я могу сделать по-другому.
models.py
from django.db import models
from home.models import TimestampedModel
from .managers import AlbumManager, ImageManager
class Album(TimestampedModel):
title = models.CharField(max_length=255)
objects = AlbumManager()
class Image(TimestampedModel):
image = models.ImageField(upload_to='img/%Y/%m/%d/')
album = models.ForeignKey(Album, on_delete=models.CASCADE)
objects = ImageManager()
Manager.py
from django.db import models
class AlbumManager(models.Manager):
def create_album(self, request):
from .models import Image
# Data collection
title = request.POST.get('title', '')
images = request.FILES.getlist('images', [])
# Validations
errors = []
if not title:
errors.append('Please enter a title.')
if not images:
errors.append('Please upload at least one image.')
# Return failure
if errors:
return (False, errors)
# Album creation
album = self.create(title=title)
# Image creation
for image in images:
Image.objects.create_image(image=image, album=album)
# Return success
len_images = len(images)
return (True, 'You have successfully uploaded %d image%s to the album \'%s\'.' % (len_images, '' if len_images == 1 else 's', title))
class ImageManager(models.Manager):
def create_image(self, **kwargs):
from io import StringIO
from PIL import Image
# Validations (raise error)
if 'image' not in kwargs and 'album' not in kwargs:
raise TypeError("create_image() missing 2 required keyword arguments 'image' and 'album'")
elif 'image' not in kwargs:
raise TypeError("create_image() missing 1 required keyword argument 'image'")
elif 'album' not in kwargs:
raise TypeError("create_image() missing 1 required keyword argument 'album'")
# Downscale image if necessary
image = Image.open(kwargs['image'])
imagefile = StringIO(image)
width, height = image.size
if width > height:
max_width = float(960)
max_height = float(720)
ratio = min(max_width / width, max_height / height)
width, height = (width * ratio, height * ratio)
elif width < height:
max_width = float(720)
max_height = float(960)
ratio = min(max_width / width, max_height / height)
width, height = (width * ratio, height * ratio)
else:
max_width = float(720)
ratio = max_width / width
width, height = (width * ratio, height * ratio)
# File operations
imagefile = StringIO()
resizedImage.save(imagefile, 'JPEG')
filename = hashlib.md5(imagefile.getvalue()).hexdigest() + '.jpeg'
imagefile = open(os.path.join('/tmp', filename), 'w')
resizedImage.save(filename, 'JPEG')
# imagefile = open(os.path.join('/tmp', filename), 'r')
# content = django.core.files.File(imagefile)
# Return image object
return self.create(image=resizedImage, album=kwargs['album'])
Редактировать 1
Вот последнее полученное сообщение об ошибке:
Internal Server Error: /images/create/
Traceback (most recent call last):
File "/home/matt/Repositories/mtm/env/lib/python3.5/site-packages/django/core/handlers/exception.py", line 34, in inner
response = get_response(request)
File "/home/matt/Repositories/mtm/env/lib/python3.5/site-packages/django/core/handlers/base.py", line 115, in _get_response
response = self.process_exception_by_middleware(e, request)
File "/home/matt/Repositories/mtm/env/lib/python3.5/site-packages/django/core/handlers/base.py", line 113, in _get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/home/matt/Repositories/mtm/images/views.py", line 16, in create
valid, response = Album.objects.create_album(request)
File "/home/matt/Repositories/mtm/images/managers.py", line 29, in create_album
Image.objects.create_image(image=image, album=album)
File "/home/matt/Repositories/mtm/images/managers.py", line 51, in create_image
imagefile = StringIO(image)
TypeError: initial_value must be str or None, not PngImageFile
Редактировать 2
views.py
from django.shortcuts import render, redirect
from django.http import HttpResponseBadRequest
from django.contrib import messages
from .models import Album
def create(request):
if request.method != 'POST':
return HttpResponseBadRequest()
valid, response = Album.objects.create_album(request)
if not valid:
for error in response:
messages.error(request, error)
else:
messages.success(request, response)
return redirect('users:index')
AlbumManager (Manager.py)
См. Выше.