我应该在Django中使用单独的表而不是多对多的字段

时间:2011-07-12 01:10:48

标签: django django-models

我需要将一个或多个类别分配给提交列表,我最初使用一个带有两个外键的表来实现这一点,直到我意识到Django有一个多对多的字段,但是根据文档我还没有能够复制我对原始表所做的事情。

我的问题是:使用多对多字段而不是手动创建关系表是否有好处?如果更好,是否有任何关于使用Django提交和检索多对多字段的示例?

1 个答案:

答案 0 :(得分:0)

来自Many-to-Many relationships上的Django文档:

  

当你只处理简单的多对多关系时   作为混合和匹配的比萨饼和浇头,标准的ManyToManyField   是你所需要的全部。但是,有时您可能需要关联数据   与两个模型之间的关系。

简而言之:如果你有一个简单的关系,那么Many-To_Many字段会更好(为你创建和管理额外的表格)。如果您需要多个额外的细节,那么使用外键创建您自己的模型。所以这取决于具体情况。

更新: - 按要求提供的示例:

来自文档:

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)

您可以看到此示例中除了多对多关系之外,还保留了成员资格详细信息(date_joinedinvite_reason)。

然而,从文档的简化示例:

class Topping(models.Model):
    ingredient = models.CharField(max_length=128)

class Pizza(models.Model):
    name = models.CharField(max_length=128)
    toppings = models.ManyToManyField(Topping)

似乎不需要任何额外的数据,因此没有额外的模型。

更新2: -

如何删除关系的示例。

在第一个例子中,我给了你额外的模型Membership,你只需删除关系及其细节,就像普通模型一样。

for membership in Membership.objects.filter(person__pk=1)
    membership.delete()

中提琴!很容易就像馅饼一样。

对于第二个示例,您需要使用.remove() (或.clear()删除所有内容)

apple = Toppings.objects.get(pk=4)
super_pizza = Pizza.objects.get(pk=12)

super_pizza.toppings.remove(apple)
super_pizza.save()

那一个也完成了!