数据库设计ManyToMany,OneToMany,ManyToOne,Django模型

时间:2012-12-15 17:51:16

标签: django-models database-schema

就数据库设计适用于具有特定关系的Django应用程序而言,我感到很困惑。我一直在查看以下数据库架构:http://www.databaseanswers.org/data%5Fmodels/customers_and_orders/index.htm

我对Customer_addresses与客户和地址之间的关系感到困惑。

我知道:

  • 一个客户可以拥有多个地址。
  • 许多客户可以拥有相同的(一个)地址

这是否等同于多对多关系?

  • 许多客户可以拥有多个地址?

当我在django中构建模型时,我已经(简化):

class Customer_Address(models.Model):
    customer = models.ManyToManyField('inventory.Customer')
    address = models.ManyToManyField('inventory.Address')

这是对的吗?或者这更有意义:

class Customer_Address(models.Model):
    customer = models.ForeignKeyField('inventory.Customer')
    address = models.ManyToManyField('inventory.Address')

更新的问题:

基于它是多对多关系的想法。 有一个ManyToMany关系,需要两个ManyToManyFields吗?

基于以下内容: http://en.wikipedia.org/wiki/Many-to-many_%28data_model%29

由于Django支持ManyToManyFields,我甚至不需要联结表吗? 如果我确实使用了联结表(Customer_addresses),那么文章似乎意味着使用两个OneToMany关系,这不就是这样的两个外键吗?

class Customer_Address(models.Model):
    customer = models.ForeignKeyField('inventory.Customer')
    address = models.ForgeinKeyField('inventory.Address')

更新的问题:

现在我们知道Django构建了中间表,并且不需要表Customer_Addresses。哪个表应该有ManyToManyfield?客户表?或地址表?

示例:https://docs.djangoproject.com/en/dev/topics/db/models/#intermediary-manytomany

在Person / Groups示例中.. Groups具有ManyToManyField。是否有任何理由无法在Person表中定义ManyToManyfield?

2 个答案:

答案 0 :(得分:6)

总结

第一个问题。

当关系表明

  • 一个客户可以拥有多个地址。

  • 许多客户可以拥有相同的(一个)地址

显然是多对多的关系并始终使用 ManyToManyField

现在提出第二个问题。

如果您想要一个在两个多对多实体之间有额外字段的中间表(表/模型),该怎么办

创建一个新模型,其中包含来自其他两个模型的ForiegnKey。如在

class Person(models.Model):
    name = models.CharField(max_length=128)

    def __unicode__(self):
        return self.name

class Group(models.Model):
    name = models.CharField(max_length=128)
    members = models.ManyToManyField(Person, through='Membership')

    def __unicode__(self):
        return self.name

class Membership(models.Model):
    person = models.ForeignKey(Person)
    group = models.ForeignKey(Group)
    date_joined = models.DateField()
    invite_reason = models.CharField(max_length=64)

了解更多Read

答案 1 :(得分:2)

似乎我没有足够的积分来回复评论。所以,回答你的问题above:实际上没有区别。作为the example in the Django documentation shows,您可以查询Person所属的组集以及属于组的人员集:

>>> ringo = Person.objects.create(name="Ringo Starr")
>>> paul = Person.objects.create(name="Paul McCartney")
>>> beatles = Group.objects.create(name="The Beatles")
>>> m1 = Membership(person=ringo, group=beatles,
...     date_joined=date(1962, 8, 16),
...     invite_reason= "Needed a new drummer.")
>>> m1.save()
>>> beatles.members.all() # Get all Persons of a Group here
[<Person: Ringo Starr>]
>>> ringo.group_set.all() # Get all Groups for a Person here
[<Group: The Beatles>]
>>> m2 = Membership.objects.create(person=paul, group=beatles,
...     date_joined=date(1960, 8, 1),
...     invite_reason= "Wanted to form a band.")
>>> beatles.members.all()
[<Person: Ringo Starr>, <Person: Paul McCartney>]