Salvando objeto com relação ManyToMany

votos
0

Eu tenho modelos (exemplo simplificado):

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)

Quero atribuir a tarefa a algum grupo de pessoas e adicionar todas as pessoas que pertencem a esse grupo, bem, como algumas outras pessoas mais tarde (ou remover determinada pessoa da tarefa). Obviamente salvar não será executada porque objeto não tem id quando quer adicionar muitos-para-muitos objetos de relacionamento. Como lidar com essa situação? Eu tentei salvar apenas antes de adicionar pessoas a tarefa e, em seguida, salvando novamente, mas isso não funcionou.

relação
chriss

Publicado 09/01/2009 em 13:14
fonte usuário
Em outras línguas...                            


2 respostas

votos
1

Aqui está como eu faria isso. Adicione um grupo separado para cada tarefa, e, opcionalmente, inicializar cada grupo com um outro:

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's 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()

Agora você pode reutilizar seus subgrupos, mais você pode determinar o que os "grupos de base" são, como Contabilidade e Vendas contra "equipe de Contabilidade 3", por verificar se parent_group é nulo. Principalmente, porém, você não está duplicando uma "lista de pessoas" em dois lugares.

Respondeu 10/01/2009 em 00:32
fonte usuário

votos
0

Aqui está um exemplo que não envolve substituindo salvar. Parece mais simples do que o que você está fazendo.

Respondeu 09/01/2009 em 13:18
fonte usuário

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more