Django模型ManyToMany和外键

时间:2012-07-11 03:38:46

标签: python database django models relationships

尝试更好地处理django数据库关系的处理方式。 任何想法都表示赞赏。

考虑以下示例模型:

class Things(models.Model):
    name = models.CharField(max_length=20)

class Stuff(models.Model):
    name = models.CharField(max_length=20)
    information = models.ManyToManyField('Information')
    things = models.ForeignKey('Things')

class Information(models.Model):
    name = models.CharField(max_length=20)
    stuff = models.ForeignKey('Stuff')

syncdbAttributeError: 'ManyToManyField' object has no attribute 'ForeignKey'导致错误。如果我在ManyToManyField模型中包含 Foreign KeyStuff字段,则会出现错误。

有没有办法可以让这两种关系存在?谢谢你的任何想法。

3 个答案:

答案 0 :(得分:4)

如果您想知道每个information有多少stuff被关联,django会提供一个默认manager,可以让您倒退;为此,您不需要stuff中的外键。

class Things(models.Model):
    name = models.CharField(max_length=20)

class Stuff(models.Model):
    name = models.CharField(max_length=20)
    information = models.ManyToManyField('Information')
    things = models.ForeignKey('Things')

class Information(models.Model):
    name = models.CharField(max_length=20)

此模型允许您执行以下查询:

  • information stuff的{​​{1}}是什么?”
  • “对于X stuffY是什么链接的?”
  • information stuff information”{+ 1}}和thing

此外,每个Z允许您有多个information,每个stuff允许多个stuff

一开始写下这些问题将有助于您开发准确的模型,而无需在数据库中建立不必要的链接/关系。

答案 1 :(得分:0)

我的django版本提供了更多信息:

Error: One or more models did not validate:
foo.stuff: Reverse query name for m2m field 'information' clashes with field 'Information.stuff'. Add a related_name argument to the definition for 'information'.
foo.information: Reverse query name for field 'stuff' clashes with m2m field 'Stuff.information'. Add a related_name argument to the definition for 'stuff'.

这可能足以让你前进。为信息与资料之间的related_name关系和ManyToManyField关系定义ForeignKey ...

information = models.ManyToManyField('Information', related_name='stuff_many_set')
stuff = models.ForeignKey('Stuff', related_name = 'info_set')

然后syncdb会很高兴。当然,你应该确定你需要两种关系。在这里使用通用实体名称看起来可能存在一些混淆。

答案 2 :(得分:0)

从根本上说,你会得到这样的错误:

$python manage.py syncdb
Error: One or more models did not validate:
t.stuff: Reverse query name for m2m field 'information' clashes with field  'Information.stuff'. Add a related_name argument to the definition for 'information'.
t.information: Reverse query name for field 'stuff' clashes with m2m field 'Stuff.information'. Add a related_name argument to the definition for 'stuff'.

为什么呢?很简单,你有两个相互引用的表,这里的问题是,当应用反向查找时,django将生成相同的名称,从而产生冲突。

要修复此问题,例如错误状态,您需要以这种方式添加related_name django知道如何区分不同的反向调用。

from django.db import models

class Things(models.Model):
    name = models.CharField(max_length=20)

class Stuff(models.Model):
    name = models.CharField(max_length=20)
    information = models.ManyToManyField('Information', related_name = 'information_information')
    things = models.ForeignKey('Things')

class Information(models.Model):
    name = models.CharField(max_length=20)
    stuff = models.ForeignKey('Stuff', related_name = 'information_stuff')

很抱歉我的名字不是很有创意,这应该有用。