Django - 如何构建适合的中间m2m模型? /最佳实践

时间:2016-05-03 16:59:57

标签: django relationship models m2m django-intermediate-table

首先,我必须承认,我对所有这些编码工作都很陌生,但由于我自己无法找到合适的解决方案并且学习编码可能是最好的方法。

无论如何,我试图建立一个应用程序来展示不同的冠军,锦标赛和类似的东西。在阅读了Django文档后,我发现我必须使用中间模型作为更好的方法。我的旧models.py看起来像这样:

class Person(models.Model):
    first_name = models.CharField(max_length=64)
    last_name = models.CharField(max_length=64)
    [...]

class Team(models.Model):
    name = models.CharField(max_length=64)
    team_member_one = models.ForeignKey(Person)
    team_member_two = models.ForeignKey(Person)

class Championship(models.Model):
    name = models.CharField(max_length=128)
    status = models.BooleanField(default=True)

class Titleholder(models.Model):
    championship = models.ForeignKey(Championship)
    date_won = models.DateField(null=True,blank=True)
    date_lost = models.DateField(null=True,blank=True)
    titleholder_one = models.ForeignKey(Person,related_name='titleholder_one',null=True,blank=True)
    titleholder_two = models.ForeignKey(Person,related_name='titleholder_two',null=True,blank=True)

锦标赛可以由个人或团队赢得,取决于它是单打还是团队冠军,这就是为什么我必须在Titleholder类中使用外键。看Django documentation这似乎是错误的。另一方面,对于我作为初学者,示例中的中间模型似乎并不适合我的模型。

长话短说:有人能指出我正确的方向如何以正确的方式建立模型吗?注意:这只是一个关于如何构建模型并在Django管理员中显示模型的问题,我甚至不谈到现在构建模板。

非常感谢帮助!先谢谢你们。

1 个答案:

答案 0 :(得分:0)

所以我会从头开始接受它。你似乎对E-R数据库建模有些新意。如果我想做你做的事情,我会按照以下方式创建我的模型。

首先,团队将成为我的角落" model(我使用这个术语来表示没有任何FK字段的模型),然后Person模型将发挥如下作用。

class Team(models.Model):
    name = models.CharField(max_length=64)

class Person(models.Model):
    first_name = models.CharField(max_length=64)
    last_name = models.CharField(max_length=64)
    team = models.ForeignKey(to=Team, null=True, blank=True, related_name='members')

这有效地使模型可扩展,即使你在一个团队中永远不会有两个以上的人,这也是很好的做法。

接下来是冠军模型。我将这个模型直接与Person模型连接,作为与' through'的多对多关系。模型如下。

class Championship(models.Model):
    name = models.CharField(max_length=64)
    status = models.BooleanField(default=False) # This is not a great name for a field. I think should be more meaningful.
    winners = models.ManyToManyField(to=Person, related_name='championships', through='Title')

class Title(models.Model):
    championship = models.ForeignKey(to=Championship, related_name='titles')
    winner = models.ForeignKey(to=Person, related_name='titles')
    date = models.DateField(null=True, blank=True)

根据我的理解,这就是我能做到的方式。我相信我并不理解你所做的一切。随着我的理解发生变化,我可能会修改这些模型以满足我的需要。

可以采用的另一种方法是使用GenericForeignKey字段创建一个字段,该字段可以是Team模型或Person模型的FK。或者可以改变的另一件事是你可以添加另一个模型来保存每次冠军赛的细节。有很多方法可以解决,没有一种正确的方法。

如果您有任何疑问,或有任何我无法解决的问题,请与我们联系。我会根据需要尝试修改答案。