как правильно переопределить метод сохранения в django? - PullRequest
0 голосов
/ 06 мая 2020

У меня есть модель изображения, в которую я могу загружать изображения, и я хочу оптимизировать их с помощью подушки, я сделал это, но есть три проблемы:

  1. изображения не сохраняются в правильном папка.
  2. django имеет функцию, когда есть два файла с одинаковым именем django добавляет случайную строку к своему имени, но теперь с двумя изображениями с одинаковым именем загружается только одно.
  3. также загружаются исходные изображения.
class Images(models.Model):
    image1 = models.ImageField(upload_to='images/%Y/', validators=[FileExtensionValidator(allowed_extensions=['png', 'jpg', 'jpeg', 'gif'])])
    image2 = models.ImageField(upload_to='images/%Y/', validators=[FileExtensionValidator(allowed_extensions=['png', 'jpg', 'jpeg', 'gif'])])

    def save(self, *args, **kwargs):
        im = Image.open(self.image1).convert('RGB')
        im2 = Image.open(self.image2).convert('RGB')
        im.save(self.image1.path,"JPEG",optimize=True,quality=75)
        im2.save(self.image2.path,"JPEG",optimize=True,quality=75)
        super(Images, self).save(*args, **kwargs) 

MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
MEDIA_URL = '/media/'

1 Ответ

0 голосов
/ 06 мая 2020

Ну, код сам по себе в порядке, Однако Images модель не подходит, вы можете создать что-то вроде

Я исправлю это STRUCTURE-WISE сначала.

class Image(models.Model):
    my_other_model = models.ForeignKey(MyOtherModel, ..., related_name='images')
    image = models.ImageField(upload_to='images/%Y/',
                              validators=[FileExtensionValidator(allowed_extensions=
                                                        ['png', 'jpg', 'jpeg', 'gif']
                                                      )])

Теперь каждый экземпляр MyOtherModel имеет .images, и вы можете создать столько изображений, сколько захотите, вместо двух

Вернуться наверх c .. Если это работает на вас, это правильно, ОДНАКО , задействовано более django, позвольте объяснить

    def save(self, *args, **kwargs):
        im = Image.open(self.image1).convert('RGB') # open image1, Put it in RAM
        im2 = Image.open(self.image2).convert('RGB') # open image2, Put it in RAM
        im.save(self.image1.path,"JPEG",optimize=True,quality=75) # process image1
        im2.save(self.image2.path,"JPEG",optimize=True,quality=75) # process image2
        super().save(*args, **kwargs) # easier syntax for python3

Теперь я хочу, чтобы вы сравнили приведенное выше с тем, что ниже.

    def save(self, *args, **kwargs):
        im = Image.open(self.image1).convert('RGB') # open image1, Put it in RAM
        im.save(self.image1.path,"JPEG",optimize=True,quality=75) # process image1
        img.close() # remove from RAM
        im2 = Image.open(self.image2).convert('RGB') # open image2, Put it in RAM
        im2.save(self.image2.path,"JPEG",optimize=True,quality=75) # process image2
        im2.close() # remove from RAM
        super().save(*args, **kwargs) # easier syntax for python3

Однако это все равно неверно. Потому что каждый раз, когда он сохраняется, он будет делать все это снова, вы хотите сделать это только при первом сохранении, при создании модели, верно? Если да .. Читайте дальше.

Исправление CODE-WISE

    def save(self, *args, **kwargs):
        old_pk = self.pk # pk is created on saving, We didn't call super().save() yet!
        # so the pk should be None if this is the creation phase.

        if old_pk is None:
            im = Image.open(self.image1).convert('RGB') # open image1, Put it in RAM
            im.save(self.image1.path,"JPEG",optimize=True,quality=75) # process image1
            im1.close() # remove from RAM
            im2 = Image.open(self.image2).convert('RGB') # open image2, Put it in RAM
            im2.save(self.image2.path,"JPEG",optimize=True,quality=75) # process image2, remove from RAM
            im2.close() # remove from RAM
        super().save(*args, **kwargs) # easier syntax for python3

Я уже упоминал об этом в вопросе раньше, читая вопрос достаточно, чтобы получить точку

ПРИМЕЧАНИЯ:

  • Если вы хотите обрабатывать оба изображения одновременно, вам нужно посмотреть многопроцессорность, многопоточность или использование сельдерея.
  • FileExtensionValidator недостаточно, чтобы знать тип файла.
  • Используйте диспетчер контекста при работе с файлами, найдите выражение with as.

Вторая проблема заключается в том, что вы на самом деле не открываете изображение, а открываете изображение с помощью Images.image1.path. Вот почему загружаются исходные изображения.

Добавьте, пожалуйста, свой MEDIA_ROOT в вопрос.

Хороший способ обработки изображений с изменением размера см. в этом

...