1

我有两个具有多对多关系的模型。这是代码:

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)

当我第一次保存锦标赛时,它只保存标题。但是当我下次保存时,它也会保存玩家并将他们与锦标赛相关联。我怎样才能在比赛的同时保存它们?

4

1 回答 1

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 关系(在这种情况下,它的逻辑在任何情况下都不是很好)

save 方法本身存在一些问题,所以让我来解决这些问题:

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

上面的最后一行什么都不做。您实例化了一个 Tournament 实例,但不要将其保存到变量中。无论如何,您实际上已经有一个锦标赛实例(如果是这种情况,则称为 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)

原因是,您的视图知道哪些玩家属于哪个锦标赛,但您的模型应该与该逻辑无关。

于 2013-11-09T15:41:32.520 回答