Django: заполнение поля во время сохранения () - PullRequest
1 голос
/ 15 марта 2011

У меня есть следующая модель, содержащая FileField, где пользователь предоставляет zip-файл, содержащий изображения. Этот zip-файл обрабатывается методом process_zipfile() во время сохранения.

class Album(models.Model):
   nom = models.CharField(max_length = 200)
   added_by = models.ForeignKey(User, null=True, blank=True)
   gallery = models.ForeignKey(Gallery, null=True, blank=True)
   zip_file = models.FileField('image field .zip', upload_to=PHOTOLOGUE_DIR+"/temp",
                 help_text='Select a .zip file of images to upload into a new Gallery.')

   class Meta:
       ordering = ['nom']

   def save(self, *args, **kwargs):
      self.gallery = self.process_zipfile()
      super(Album, self).save(*args, **kwargs)

   def delete(self, *args, **kwargs):
      photos = self.gallery.photos.all()
      for photo in photos:
            photo.delete()
      self.gallery.delete()
      super(Album, self).delete(*args, **kwargs)

   def process_zipfile(self):
      if os.path.isfile(self.zip_file.path):
      ......(creates gallery object and links the photos)
      return gallery

работает нормально, за исключением того, что поле gallery (оставлено пустым в форме) не заполняется галереей, созданной process_zipfile(). Что я не так делаю?

Кроме того, метод удаления, похоже, не работает, понимаете?

Ответы [ 2 ]

0 голосов
/ 09 марта 2013

Хотя этому вопросу уже два года, я наткнулся на него, пытаясь научиться делать что-то похожее.

Загруженные файлы не записываются в их постоянное местоположение до тех пор, пока не будет сохранена модель или поле, поэтомупуть может вводить в заблуждение.В зависимости от вашей конфигурации и размера файла он обычно будет находиться в оперативной памяти (если меньше 2,5 МБ) или в каталоге tmp.Подробности см .: https://docs.djangoproject.com/en/dev/topics/http/file-uploads/#where-uploaded-data-is-stored

Если вам нужно получить дескриптор файла, прежде чем модель будет сохранена, чтобы выполнить некоторую обработку, вы можете вызвать save в поле (этопринимает два аргумента, имя файла и объект File, представляющий его содержимое, см .: https://docs.djangoproject.com/en/1.2/ref/models/fields/#django.db.models.FieldFile.save).

Поскольку вы вызываете save () внутри save (), вы, вероятно, захотитепередать необязательный save=False (при условии, что вы вызываете save() для модели где-то вниз по линии).

Решение OP сработало, потому что обработчик post-save вызывается после сохранения модели, поэтомуфайл существует в ожидаемом месте.

Альтернативные решения: принудительная обработка файла с помощью обработчика файла tmp и получение пути tmp; реализация собственного обработчика загрузки.

0 голосов
/ 28 марта 2011

Я наконец смог решить мою проблему, используя post_save и pre_delete:

def depacktage(sender, **kwargs):
    obj = kwargs['instance']
    obj.gallery = obj.process_zipfile()
    obj.zip_file = None
    post_save.disconnect(depacktage, sender=Album)
    obj.save()
    post_save.connect(depacktage, sender=Album)

def netoyage(sender, **kwargs):
        obj = kwargs['instance']
        if obj.gallery:
                if obj.gallery.photos:
                        photos = obj.gallery.photos.all()
                        for photo in photos:
                                photo.delete()
                gal = Gallery.objects.get(pk = obj.gallery.pk)
                pre_delete.disconnect(netoyage, sender=Album)
                gal.delete()
                pre_delete.connect(netoyage, sender=Album)

pre_delete.connect(netoyage, sender=Album)
post_save.connect(depacktage, sender=Album)
...