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.
CodePudding user response:
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()
CodePudding user response:
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 ofGroupPostsModel
(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.