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
source to share
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.
source to share