Saving an Object with a ManyToMany Relationship

I have models (simplified example):

class Group(models.Model):
  name = models.CharField(max_length = 32)

class Person(models.Model):
  group = models.ForeignKey(Group)

class Task(models.Model):
  group = models.ForeignKey(Group)
  people = models.ManyToManyField(Person)

  def save(self, **kwargs):
    ppl = Person.objects.all().filter(group = self.group)
    for p in ppl:
      self.people.add(p)
    super(Task, self).save(**kwargs)

      

I want to assign a task to some groups of people and add all the persons that belong to that group as well as some other people later (or remove a specific person from the task). Obviously, the persistence will fail because the object has no identifier when it wants to add many-to-many relationship objects. How to deal with this situation? I tried saving before adding people to the task and then saving again, but it didn't work.

welcomes
Chriss

0


source to share


2 answers


Here's an example that doesn't include undoing a save. It looks simpler than what you are doing.



0


source


This is how I will do it. Create a separate group for each task, and possibly initialize each group differently:

class Person(models.Model):
    name = models.CharField(max_length=64)

class Group(models.Model):
    name = models.CharField(max_length=32)
    people = models.ManyToManyField(Person)
    parent_group = models.ForeignKey(Group, null=True, blank=True)

    def save(self, **kwargs):
        # copy parent people in to this group if this is a new instance and parent_group is set
        if not self.id and self.parent_group:
            for p in self.parent_group.people:
                self.people.add(p)
        super(Group, self).save(**kwargs)

class Task(models.Model):
    group = models.ForeignKey(Group)

def use_case():
    Group(name='empty group').save()

    group = Group.objects.get(name='Accounting')
    accounting_subgroup = Group(name='Accounting Copy', parent_group=group)
    accounting_subgroup.people.remove(person1)
    accounting_subgroup.people.remove(person2)
    accounting_subgroup.save()

    task = Task(group=accounting_subgroup)
    task.save()

      



You can now reuse your subgroups, and you can also define what the "base groups" such as Accounting and Sales and Accounting Command 3 are by checking if parent_group is null. Basically, however, you don't duplicate the "people list" in two places.

+1


source







All Articles