在ManyToMany关系中保存()

时间:2013-11-09 13:36:07

标签: python django python-2.7

我有两个与ManyToMany关系的模型。这是代码:

class Player(models.Model):

    first_name = models.CharField(max_length = 30, verbose_name = u"First name")
    last_name = models.CharField(max_length = 50, verbose_name = u"Last name")

    def __unicode__(self):
        return "%s %s" % (self.last_name, self.first_name)

class Tournament(models.Model):
    title = models.CharField(max_length = 100, verbose_name = u"Tournament's title")
    players = models.ManyToManyField(Player,verbose_name = u"Tournament's players")

    def __unicode__(self):
        return self.title

    def save(self, **kwargs):
        Tournament(title = self.title)
        all_players = Player.objects.all()
        for member in all_players:
            member_of_tournament = member.tournament_set.filter(title = self.title)
            for j in member_of_tournament:
                print member.tournament_set.filter(title = self.title)
                self.players.add(member)

        super(Tournament, self).save(**kwargs)

当我第一次保存锦标赛时,它只保存标题。但是当我下次保存的时候它也可以节省玩家并将它们与锦标赛联系起来。如何在锦标赛的同时保存它们?

1 个答案:

答案 0 :(得分:4)

我认为你有很多问题:

class Tournament(models.Model):
    title = models.CharField(max_length = 100, verbose_name = u"Tournament's title")
    players = models.ManyToManyField(Player,verbose_name = u"Tournament's players")

    def __unicode__(self):
        return self.title

    def save(self, **kwargs):
        Tournament(title = self.title)
        all_players = Player.objects.all()
        for member in all_players:
            member_of_tournament = member.tournament_set.filter(title = self.title)
            for j in member_of_tournament:
                print member.tournament_set.filter(title = self.title)
                self.players.add(member)

        super(Tournament, self).save(**kwargs)

一般来说,你不希望在模型保存方法中有你的m2m关系(在这种情况下,它的逻辑在任何情况下都不是很好)

你在保存方法本身有一些问题,所以让我解决这些问题:

def save(self, **kwargs):
    Tournament(title = self.title)

上面的最后一行无能为力。您实例化锦标赛的实例,但不将其保存到变量。实际上你已经有了锦标赛的实例(如果是这种情况,称为self)。

    all_players = Player.objects.all()
    for member in all_players:
        member_of_tournament = member.tournament_set.filter(title = self.title)

在这里,您遍历数据库中的所有玩家,无论他们是否符合您的查询。

这实在是效率低下。

在下一行中,您有member_of_tournament = member.tournament_set.filter(title = self.title)。这是复数,因此您应该调用此members_of_tournament,因为这是一个数组/列表/查询集。

老实说,我不确定剩下的策略是什么,但足以说,你不应该那样做,可能。

您应该熟悉整个自定义保存方法,并在您的视图中推动此操作,您应该执行以下操作:

tournament = Tournament(title=title)
tournament.save()
players_i_care_about = [players, go, here]

tournament.players = players_i_care_about #(removes all players and saves new players)

for player in players_i_care_about:
    tournament.players.add(player) #(only adds these players, doesn't remove any players)

原因是,你的观点知道哪些球员属于什么锦标赛,但你的模型应该与那个逻辑无关。