为什么 Django Rest Framework on_delete 在图像和文件字段上无法按预期工作?
Why on_delete of Django Rest Framework not work as expected on Image and File Fields?
当我使用 Django rest 删除父项 table 时,由于 on_delete 它删除了子项 table 也(由于外键)但是子项的图像和文件内容table 未删除。
我也想删除那些图像和文件..!
怎么做..?
我的table
1:Group
2:Posts
一对多关系
我删除群组table如下:
GroupsModel.objects.filter(id=py_data.get('group_id')).delete()
群组模型:
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'
我也想自动删除图片和文档文件。
on_delete=models.CASCADE
on a ForeignKey
是在数据库模式上编写和管理的内容。在删除时删除子模型的不是 Django,而是您的数据库(MySQL、Postgres 等)自动检测外键故障并执行级联操作(如约束)。
models.ImageField
和 models.FileField
(在数据库级别)只是一个 CharField,其中包含文件在文件系统上的位置。数据库无法删除文件,因此您不能将此操作委托给数据库。
如果您想自动删除模型 .delete()
上的文件,您有多种可能的策略:
- 定期检查每个文件是否存在模型(如果不存在,请删除文件)
- 覆盖
GroupPostsModel
的 .delete()
方法(但只有当您在模型的实例上调用 .delete()
时它才会起作用,而不是在查询集上,就像在您的示例中那样)
- 在删除端点上添加删除功能。
删除实例时,不会删除引用的文件,因为 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
方法不会在你写的queryset中被调用,你需要单独删除每个实例:
for instance in GroupsModel.objects.filter(id=py_data.get('group_id')):
instance.delete()
当我使用 Django rest 删除父项 table 时,由于 on_delete 它删除了子项 table 也(由于外键)但是子项的图像和文件内容table 未删除。 我也想删除那些图像和文件..! 怎么做..?
我的table 1:Group 2:Posts 一对多关系
我删除群组table如下:
GroupsModel.objects.filter(id=py_data.get('group_id')).delete()
群组模型:
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'
我也想自动删除图片和文档文件。
on_delete=models.CASCADE
on a ForeignKey
是在数据库模式上编写和管理的内容。在删除时删除子模型的不是 Django,而是您的数据库(MySQL、Postgres 等)自动检测外键故障并执行级联操作(如约束)。
models.ImageField
和 models.FileField
(在数据库级别)只是一个 CharField,其中包含文件在文件系统上的位置。数据库无法删除文件,因此您不能将此操作委托给数据库。
如果您想自动删除模型 .delete()
上的文件,您有多种可能的策略:
- 定期检查每个文件是否存在模型(如果不存在,请删除文件)
- 覆盖
GroupPostsModel
的.delete()
方法(但只有当您在模型的实例上调用.delete()
时它才会起作用,而不是在查询集上,就像在您的示例中那样) - 在删除端点上添加删除功能。
删除实例时,不会删除引用的文件,因为 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
方法不会在你写的queryset中被调用,你需要单独删除每个实例:
for instance in GroupsModel.objects.filter(id=py_data.get('group_id')):
instance.delete()