代码之家  ›  专栏  ›  技术社区  ›  fmakawa

当模型有多个文件时,上载新版本时,从特定模型字段中删除文件。字段而不删除所有内容Django

  •  0
  • fmakawa  · 技术社区  · 8 年前

    我的问题是关于孤立文件和我的模型使用多个文件字段的事实。我有一个用户模型,它有一个配置文件图像字段和一个cv字段。用户可以更新这些字段,这些字段工作正常,但保留旧文件。现在,我已经在网上查看了各种解决方案,创建了自己的etc,但它并没有正常工作。我的解决方案(见下文)的问题是,它删除了当时与该实例关联的所有旧媒体文件,即使我只更改了一个值。此外,每个字段都有自己的目录路径,因此不会因为共享相同的目录路径而导致递归删除。如果我同时更改这两个字段,这很好,因为更改和以前的文件都会被删除,但人们通常只更改一个值,那么我该如何解决这个问题?出于各种原因,我不想使用django cleanup。

    型号。py公司

    def teacher_avatar_directory_path(instance, filename):
        # file will be uploaded to MEDIA_ROOT/user_<id>/<filename>
        return 'teachers/avatar/{0}/{1}'.format(instance.user.email.replace(" ", "_").lower(), filename)
    def teacher_cv_directory_path(instance, filename):
        # file will be uploaded to MEDIA_ROOT/user_<id>/<filename>
        return 'teachers/cv/{0}/{1}'.format(instance.user.email.replace(" ", "_").lower(), filename)
    
    
    #Teacher
    class ProfileTeacher(models.Model):
        created = models.DateTimeField(auto_now=False, auto_now_add=True, blank = False, null = False, verbose_name = 'Creation Date')
        user = models.OneToOneField(app_settings.USER_MODEL,blank=True, null=False)
        first_name = models.CharField(max_length = 400, null=True, blank = True, verbose_name = 'First Name')
        last_name = models.CharField(max_length = 400, null=True, blank = True, verbose_name = 'Surname')
        phone_number = models.CharField(max_length = 15, null=True, blank = True, verbose_name = 'Phone Number')
        cvv = models.FileField(upload_to=teacher_cv_directory_path, null=True, blank = True, verbose_name="CV")
        profile_image = models.ImageField(upload_to=teacher_avatar_directory_path,
                                          null = True,
                                          blank=True,
                                          default='/perfil.png',
                                          )
    
    
    
    #-------Model image and files clean up ----------------------------------
    @receiver(post_init, sender= ProfileTeacher)
    def backup_image_and_cv_paths(sender, instance, **kwargs):
        instance._current_image_file = instance.profile_image
        instance._current_cvv_file = instance.cvv
    
    @receiver(post_save, sender= ProfileTeacher)
    def delete_old_image(sender, instance, **kwargs):
        if hasattr(instance, '_current_image_file'):
            if instance._current_image_file != instance.profile_image.path:
                instance._current_image_file.delete(save=False)   
        if hasattr(instance, '_current_cvv_file'):
            if instance._current_cvv_file != instance.cvv.path:
                instance._current_cvv_file.delete(save=False)
    
    1 回复  |  直到 8 年前
        1
  •  1
  •   urDMG    8 年前

    可以为模型创建自定义保存方法。 Docs here

    class YourModel(models.Model):
       field_1 = ...
       field_2 = ...  
    
       def save(self, *args, **kw):
          if self.id:
    
             # Check that instance that you are sending for update have files in it
             # Get corresponding file field(s) and manually remove old file(s) according to the path
             # Store new file(s) to the file field(s)
             # Update other fields if required
    
             super().save(*args, **kwargs)