Django-如何构建适合您的中间m2m模型?/最佳做法
首先,我必须承认,我对所有这些编码的东西都很陌生,但因为我自己找不到合适的解决方案,所以学习编码可能是最好的方法 不管怎么说,我正在尝试建立一个应用程序来展示不同的冠军头衔、冠军等等。在阅读了Django文档之后,我发现我必须使用中间模型作为更好的方法。My old models.py的外观如下:Django-如何构建适合您的中间m2m模型?/最佳做法,django,relationship,models,m2m,django-intermediate-table,Django,Relationship,Models,M2m,Django Intermediate Table,首先,我必须承认,我对所有这些编码的东西都很陌生,但因为我自己找不到合适的解决方案,所以学习编码可能是最好的方法 不管怎么说,我正在尝试建立一个应用程序来展示不同的冠军头衔、冠军等等。在阅读了Django文档之后,我发现我必须使用中间模型作为更好的方法。My old models.py的外观如下: class Person(models.Model): first_name = models.CharField(max_length=64) last_name = models.
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)
冠军可以由个人或团队赢得,这取决于是单打冠军还是团队冠军,这就是为什么我必须在冠军级别上使用外键。看着这个世界,这似乎是错误的。另一方面,对于初学者来说,示例中的中间模型似乎在任何方面都不适合我的模型
长话短说:有谁能为我指出正确的方向,告诉我如何以正确的方式构建模型?注意:这只是一个关于如何构建模型并在Django管理员中显示模型的问题,我现在甚至不谈论构建模板
非常感谢您的帮助!提前谢谢各位。所以我将从头开始。您似乎对E-R数据库建模有些陌生。如果我试着做你所做的,我会用下面的方法创建我的模型 首先,团队将是我的“角落”模型(我用这个术语来表示没有任何FK字段的模型),然后人员模型将发挥作用,如下所示
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')
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)
这有效地提高了模型的可伸缩性,即使您的团队中永远不会有超过两个人,这也是一个很好的实践
接下来是冠军模式。我将把这个模型直接与Person模型连接起来,作为一个多对多的关系,通过一个“through”模型,如下所示
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')
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字段创建一个字段,该字段可以是团队模型或个人模型的FK。或者另一件可以改变的事情是,你可以添加另一个模型来保存每次锦标赛的细节。有很多方法可以做到这一点,但没有一种方法是正确的
如果你有任何问题或任何我没有解决的问题,请告诉我。我将根据需要尝试修改答案。Django的
ManyToManyField
只是自动创建和查询中间表的语法糖。如果显式地创建表,就像在这里所做的那样,那么就不需要该字段(尽管它仍然有帮助)。但是,您提出的模式存在许多问题。它们都与Django无关,这是一个SQL数据库建模的问题。我建议问一个更一般的问题(我如何对这些数据建模?以下是我尝试过的…)并用or标记它。