Как получить файл и SHA-1 дайджест загруженного файла?

4 callum [2012-01-22 04:09:00]

У меня есть эта модель в приложении Django:

class Image(models.Model):
    image_file = models.ImageField(
        upload_to='images/', 
        width_field='width',
        height_field='height'
    )
    width = models.PositiveIntegerField(
        blank = True, null = True,
        editable = False
    )
    height = models.PositiveIntegerField(
        blank = True, null = True,
        editable = False
    )

    sha1 = models.CharField(max_length=32, blank=True, editable=False)
    filesize = models.PositiveIntegerField(blank=True, null=True, editable=False)

Теперь я могу загружать изображения через админ-сайт Django. И свойства width и height сохраняются в базе данных автоматически при ее загрузке из-за специальных параметров ImageField.

Но мне также хотелось бы автоматически выработать дайджест загруженного файла размер и SHA-1 и сохранить эти свойства тоже. Как мне это сделать?

python django file-upload


2 ответа


3 Решение Burhan Khalid [2012-01-23 12:46:00]

Это было какое-то время, но что-то вроде этого должно работать:

import hashlib
class Image(models.Model):
#...
    def save(self, *args, **kwargs):
        super(Image, self).save(*args, **kwargs)
        f = self.image_file.open('rb')
        hash = hashlib.sha1()
        if f.multiple_chunks():
           for chunk in f.chunks():
              hash.update(chunk)
        else:    
              hash.update(f.read())
        f.close()
        self.sha1 =  hash.hexdigest()
        self.filesize = self.image_file.size 

EDIT: Добавлено предложение Дэна о чтении куском. Размер блока по умолчанию - 64 КБ.


1 D.Shawley [2012-01-22 04:22:00]

Я не уверен, что вы можете сделать это автоматически. Но ImageField также является FileField, поэтому вы всегда можете открыть файл и вычислить контрольную сумму, используя hashlib.sha1. Вам нужно будет прочитать файл, чтобы вычислить контрольную сумму, чтобы вы могли одновременно нюхать размер.

Прошло некоторое время с тех пор, как я использовал Django ORM, но я считаю, что есть способ написать метод, который вызывается всякий раз, когда экземпляр модели сохраняется или читается из основного хранилища. Это было бы хорошим местом для расчета.