Home > Mobile >  In django how to remove a string value storing parent id from child table when the parent is deleted
In django how to remove a string value storing parent id from child table when the parent is deleted

Time:08-12

I am storing some values from the parent in the child table as csv in a character field. Problem is when the parent is deleted, though the m2m relation is deleted, the value that was selected in the child table string remains as it is. How do I take care of it? Will I have to run a post_save method on the parent to access all the children's string and remove the value from there. There will be a lot of performance issues.

eg:

class Child1(models.Model):
    name = models.CharField(max_length=30, unique=True)

class Teacher1(models.Model):
    name = models.CharField(max_length=30, unique=True)

    children = models.ManyToManyField(
            Child1,
            blank=True,null=True,
            related_name='children')
   child_list =  models.CharField(max_length=500, unique=True)

Above, the child_list is populated with the child names as CSV, when the children are selected in Teacher1Admin in admin.py. But when any child is deleted, though the corresponding relationships are deleted, the name of the child remains in the Teacher table in the child_list. How can this be removed, whenever the Child1 table is edited/ child deleted, without much performance overhead?

CodePudding user response:

Remove child_list from the model, and add a property instead.

class Teacher1(models.Model):
    name = models.CharField(max_length=30, unique=True)

    children = models.ManyToManyField(
            Child1,
            blank=True,null=True,
            related_name='children')

    @property
    def child_list(self): 
        return self.children.values("name") 

You could probably make it a cached property too for performance.

This will avoid having to store the same data twice. What you have right now is a poorly normalised database, and it needs fixing.

CodePudding user response:

The ideal solution is to remove child_list from Teacher1 class and just use children to get the names of the related children.

If you insist on keeping child_list, you just need to parse the value, remove the child and then update the field. It might looks something like this:

def remove_from_teacher(teacher, name):
  names = teacher.child_list.split(',')
  names.remove(name)
  teacher.child_list = ','.join(names)
  teacher.save()
  • Related