【问题标题】:Database Design ManyToMany, OneToMany, ManyToOne, Django model数据库设计 ManyToMany、OneToMany、ManyToOne、Django 模型
【发布时间】:2012-12-15 17:51:16
【问题描述】:

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

我对 Customer_addresses 和 Customers 以及 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')

更新问题:

基于它是多对多关系的想法。 一个多对多关系是否需要两个多对多字段?

基于以下几点: 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?

【问题讨论】:

  • 如果在您的情况下,许多客户可以拥有与多对多关系相同的地址。
  • 那么第一个模型将是要走的路吗?
  • 是的,第一个对你有用。冒昧的风险,我认为你需要修改你的数据库基础,请阅读en.wikipedia.org/wiki/Many-to-many_%28data_model%29
  • 感谢您的链接。我已经读过了,我想让我感到困惑的是关于 ManyToManyFields 的最后一个声明。由于 Django 允许使用 ManyToManyfields.. 我不需要联结表吗?我要更新我的问题。
  • 我真的很抱歉错过了那部分。这实际上是一个非常好的问题。不,你不需要两个 ManyToManyFields,Django 后端处理所有事情docs.djangoproject.com/en/dev/ref/models/fields/…

标签: django-models database-schema


【解决方案1】:

总结

第一个问题。

当关系表明

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

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

这显然是多对多关系,并且总是使用 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

【讨论】:

  • Group 模型获得 ManyToMany 字段是否有特殊原因。为什么没有 groups = models.ManyToManyfield(Group, through='Membership')。这会改变什么吗?
【解决方案2】:

看来我没有足够的积分来回复 cmets。所以,回答你的问题above:实际上没有区别。作为the example in the Django documentation shows,您可以查询一个Person所属的Groups集合以及属于一个Group的Persons集合:

>>> 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>]

【讨论】:

    猜你喜欢
    • 2016-04-29
    • 1970-01-01
    • 2021-07-21
    • 1970-01-01
    • 1970-01-01
    • 2016-10-12
    • 2011-12-14
    • 1970-01-01
    • 2011-03-07
    相关资源
    最近更新 更多