为什么django rest框架的on_delete在图像和文件字段上无法正常工作?

发布于 2025-01-19 14:00:26 字数 1313 浏览 3 评论 0原文

当我由于 on_delete 使用 Django Rest 删除父表时,它也会删除子表(由于外键),但子表的图像和文件内容不会被删除。 我也想删除那些图像和文件..! 如何做到这一点..?

我的桌子 1:团体 2:帖子 一对多关系

我按如下方式删除组表:

GroupsModel.objects.filter(id=py_data.get('group_id')).delete()

GroupsModel :

class GroupsModel(models.Model):
    group_name = models.CharField(max_length=20, unique=True)
    group_description = models.CharField(max_length=50)
    group_joining_link = models.CharField(max_length=50, default='', unique=True)
    user_id = models.ManyToManyField(UserModel, through='UserModelGroupsModel', related_name='u_g')

    class Meta:
        db_table = 'groups'

GroupPostsModel:

class GroupPostsModel(models.Model):
    post_text = models.CharField(max_length=1000)
    post_type = models.CharField(max_length=20)
    image = models.ImageField(blank=True, null=True, upload_to='post_images/')
    document = models.FileField(blank=True,null=True, upload_to='post_documents/')
    likes = models.IntegerField(default=0)
    time_stamp = models.DateTimeField(auto_now=True)
    group = models.ForeignKey(GroupsModel, on_delete=models.CASCADE)
    user = models.ForeignKey(UserModel, on_delete=models.CASCADE)

    class Meta:
        db_table = 'group_posts'

我也想自动删除图像和文档文件。

When I delete the parent table using Django rest due to on_delete it deletes the child table also (due to foreign key) but the Image and File content of the child table not deleted.
I want to delete those images and Files also..!
How to do that..?

My tables
1:Group
2:Posts
One To Many Relation

I delete the Group table as follows:

GroupsModel.objects.filter(id=py_data.get('group_id')).delete()

GroupsModel :

class GroupsModel(models.Model):
    group_name = models.CharField(max_length=20, unique=True)
    group_description = models.CharField(max_length=50)
    group_joining_link = models.CharField(max_length=50, default='', unique=True)
    user_id = models.ManyToManyField(UserModel, through='UserModelGroupsModel', related_name='u_g')

    class Meta:
        db_table = 'groups'

GroupPostsModel:

class GroupPostsModel(models.Model):
    post_text = models.CharField(max_length=1000)
    post_type = models.CharField(max_length=20)
    image = models.ImageField(blank=True, null=True, upload_to='post_images/')
    document = models.FileField(blank=True,null=True, upload_to='post_documents/')
    likes = models.IntegerField(default=0)
    time_stamp = models.DateTimeField(auto_now=True)
    group = models.ForeignKey(GroupsModel, on_delete=models.CASCADE)
    user = models.ForeignKey(UserModel, on_delete=models.CASCADE)

    class Meta:
        db_table = 'group_posts'

I want to delete image and document file also automatically.

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

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

发布评论

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

评论(2

野侃 2025-01-26 14:00:26

删除实例时,引用的文件不会被删除,因为 ImageField/FileField 只是对文件的引用。您可以重写模型的 delete 方法:

import os

class GroupPostsModel(models.Model):
    post_text = models.CharField(max_length=1000)
    post_type = models.CharField(max_length=20)
    image = models.ImageField(blank=True, null=True, upload_to='post_images/')
    document = models.FileField(blank=True,null=True, upload_to='post_documents/')
    likes = models.IntegerField(default=0)
    time_stamp = models.DateTimeField(auto_now=True)
    group = models.ForeignKey(GroupsModel, on_delete=models.CASCADE)
    user = models.ForeignKey(UserModel, on_delete=models.CASCADE)
    
    def delete(self):
       if self.image:
          if os.path.isfile(self.image.path):
             os.remove(self.image.path)

       if self.document:
          if os.path.isfile(self.document.path):
             os.remove(self.document.path)
       
       super().delete()

    class Meta:
        db_table = 'group_posts'

您编写的查询集中不会调用 delete 方法,您需要单独删除每个实例:

for instance in GroupsModel.objects.filter(id=py_data.get('group_id')):
   instance.delete()

When an instance is removed referred files are not deleted, since the ImageField/FileField is only a reference to the files. You can override the delete method of your model:

import os

class GroupPostsModel(models.Model):
    post_text = models.CharField(max_length=1000)
    post_type = models.CharField(max_length=20)
    image = models.ImageField(blank=True, null=True, upload_to='post_images/')
    document = models.FileField(blank=True,null=True, upload_to='post_documents/')
    likes = models.IntegerField(default=0)
    time_stamp = models.DateTimeField(auto_now=True)
    group = models.ForeignKey(GroupsModel, on_delete=models.CASCADE)
    user = models.ForeignKey(UserModel, on_delete=models.CASCADE)
    
    def delete(self):
       if self.image:
          if os.path.isfile(self.image.path):
             os.remove(self.image.path)

       if self.document:
          if os.path.isfile(self.document.path):
             os.remove(self.document.path)
       
       super().delete()

    class Meta:
        db_table = 'group_posts'

The delete method will not be called in the queryset you wrote, you need to delete each instance individually:

for instance in GroupsModel.objects.filter(id=py_data.get('group_id')):
   instance.delete()
┈┾☆殇 2025-01-26 14:00:26

ForeignKey 上的 on_delete=models.CASCADE 是在数据库架构上编写和管理的内容。在删除时删除子模型的不是 Django,而是您的数据库(MySQL、Postgres...)会自动检测foreignkey 上的故障并执行级联操作(如约束)。

models.ImageFieldmodels.FileField (在数据库级别)只是一个 CharField,其中包含文件在文件系统上的位置。数据库无法删除文件,因此您不能将此操作委托给数据库。

如果您希望自动删除模型.delete()上的文件,您有多种可能的策略:

  • 定期检查每个文件是否存在模型(如果不存在,则删除该文件)
  • 覆盖GroupPostsModel 的 .delete() 方法(但仅当您在模型实例上调用 .delete() 时才有效,而不是在查询集上调用,就像你的例子)
  • 添加删除端点上的删除功能。

on_delete=models.CASCADE on a ForeignKey is something written and managed on the database schema. It is not Django that delete the child model on delete, but your database (MySQL, Postgres, ...) that automaticaly detect a failure on ForeignKey and perform a Cascade action (like a contraint).

models.ImageField and models.FileField are (at database level) just a CharField with the location on the file system of your file. The database cannot remove a file, so you cannot delegate this action to the database.

If you want automatic removal of file on Model .delete(), you have multiple possible strategy :

  • Periodic check that for each file, a model exists (if not, remove the file)
  • Overwrite the .delete() method of GroupPostsModel (but it will only work if you call .delete() on an instance of the model, not on a queryset, like on your exemple)
  • Add the removal feature on the delete endpoint.
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文