Django:ManyToMany,谁最有效率?

时间:2016-04-30 08:51:35

标签: django django-models

我对两种模特的概念犹豫不决。

在我的网站上,有足球队。这些球队包含教练,球员,导演......等。

目前,我将其建模为(1):

class Team(models.Model):
    name = models.CharField(max_length=25,primary_key=True)

class Chief(models.Model):
    created_at = models.DateField(auto_now_add=True)
    team = models.ForeignKey(Team, null=False,on_delete=models.CASCADE)
    user = models.ForeignKey(User, null=False,on_delete=models.CASCADE)

class Player(models.Model):
    created_at = models.DateField(auto_now_add=True)
    team = models.ForeignKey(Team, null=False,on_delete=models.CASCADE)
    user = models.ForeignKey(User, null=False,on_delete=models.CASCADE)
    position = models.CharField(max_length=30) #3 positions posible

class Director(models.Model):
    created_at = models.DateField(auto_now_add=True)
    team = models.ForeignKey(Team, null=False,on_delete=models.CASCADE)
    user = models.ForeignKey(User, null=False,on_delete=models.CASCADE)

问题是,当我想要获得团队的所有成员(酋长,导演和玩家)时,我必须执行3个请求。 但优势在于,当我只想要所有董事时,我只是在Director实体中搜索!

我毫不犹豫地删除了这3个模型(导演,玩家和酋长)并在团队中建立了3个关系ManyToMany(2):

class Team(models.Model):
    name = models.CharField(max_length=25,primary_key=True)
    chiefs = models.ManyToManyField(User)
    directors = models.ManyToManyField(User)
    players_position1 = models.ManyToManyField(User)
    players_position2 = models.ManyToManyField(User)
    players_position3 = models.ManyToManyField(User)

哪个是(1)和(2)之间最有效的方法?

2 个答案:

答案 0 :(得分:0)

您可以使用model inheritance

<强> models.py

class TeamMember(models.Model):
    created_at = models.DateField(auto_now_add=True)
    team = models.ForeignKey(Team, null=False,on_delete=models.CASCADE)
    user = models.ForeignKey(User, null=False,on_delete=models.CASCADE)

class Chief(TeamMember):
    pass

class Director(TeamMember):
    pass

class Player(TeamMember):
    position = models.CharField(max_length=30)

<强> views.py

#Get all members
members = TeamMember.objects.all()

#Only players
players = Player.objects.all()

答案 1 :(得分:0)

class Team(models.Model):
    name = models.CharField(max_length=25,primary_key=True)

class MemberQuerySet(models.QuerySet):
    def chiefs(self):
        return self.filter(position='a')

    def directors(self):
        return self.filter(position='b')

    def players(self):
        return self.filter(position__in=['c', 'd', 'e'])

class Member(models.Model):
    created_at = models.DateField(auto_now_add=True)
    team = models.ForeignKey(Team, models.CASCADE, related_name="members")
    user = models.ForeignKey(User, models.CASCADE)
    position = models.CharField(max_length=1, choices=(
        ('a', 'chief'),
        ('b', 'director'), 
        ('c', 'player position 1'),
        ('d', 'player position 2'),
        ('e', 'player position 3'))

    objects = MemberQuerySet.as_manager()

现在你可以获得一个团队的所有成员,或者只是在数据库中只有一次点击的玩家

members = Team.objects.get(pk='someteam').members
players = Team.objects.get(pk='someteam').members.players()