开发者

Django: populating a field during save()

I have the following model containing a FileField where the user provide a zip file containing pictures. This zip file is precessed by a method called process_zipfile() during the save.

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

it works ok except that the field gallery (left blank by the form) is not populated by the gallery created by process_zipfile(). What am I doinfg wrong?

Besides, the delete method doesn't seem to work, any idea?


I was finally able to solve my problem using post_save and 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)


Although this question is two years old I came across it trying to learn how to do something similar.

Uploaded files are not written to their permanent location until either the model or the field is saved, so the path can be misleading. Depending on your configuration and the size of the file, it will typically be living in RAM (if less than 2.5 MB) or in the tmp directory. For details see: https://docs.djangoproject.com/en/dev/topics/http/file-uploads/#where-uploaded-data-is-stored

If you need to get a handle on the file, before the model is saved, in order to do some processing on it, you can call save on the field (it takes two arguments, the file name, and a File object representing its contents, see: https://docs.djangoproject.com/en/1.2/ref/models/fields/#django.db.models.FieldFile.save).

Since you would be calling save() inside the save(), you'll probably want to pass the optional save=False (assuming you're calling save() on the model somewhere down the line).

The OP's solution worked because the post-save handler is invoked after the model has been saved, so the file exists in the expected location.

Alternate solutions: forcing the file to be handled with the tmp file handler, and grab the tmp path; implement your own upload handler.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜