Django:在 save() 期间填充字段

发布于 2024-10-22 21:26:51 字数 1172 浏览 0 评论 0原文

我有以下包含 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()创建的图库填充。我做错了什么?

另外,删除方法似乎不起作用,有什么想法吗?

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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

凹づ凸ル 2024-10-29 21:26:51

我终于能够使用 post_savepre_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)

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)
跨年 2024-10-29 21:26:51

虽然这个问题已经有两年了,但我在尝试学习如何做类似的事情时遇到了它。

在保存模型或字段之前,上传的文件不会写入其永久位置,因此路径可能会产生误导。根据您的配置和文件大小,它通常位于 RAM(如果小于 2.5 MB)或 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 的解决方案之所以有效,是因为保存模型后会调用保存后处理程序,因此文件存在于预期位置。

替代解决方案:强制使用 tmp 文件处理程序处理文件,并获取 tmp 路径;实现您自己的上传处理程序。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文