2012-07-11 145 views
3

试图更好地处理如何处理django数据库关系。 任何想法表示赞赏。Django模型ManyToMany和外键

考虑下面的例子型号:

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'。如果我在Stuff模型中包含两个ManyToManyFieldForeign Key字段,则会出现错误结果。

有没有一种方法可以使这两种关系存在?感谢您的任何想法。

+0

是否存在冲突在_Stuff_中_ManyToMany_ wi th _Information_,但在_ManyToOne_中_Stuff_在_Information_中。 – Rohan 2012-07-11 04:02:40

+1

从代码示例中不可能判断出信息和资料之间的关系是否应该是一对多或多对多关系。 – user240515 2012-07-11 04:06:27

+0

这个想法是'Stuff'可以有多个'information',但'Information'引用一种'Stuff'。所以从'Stuff'到'Information'的ManyToMany,和从'Information'到'Stuff'的ForeignKey。它在我的脑海中运行得非常好,但在Django中并没有。有任何想法吗? – 2012-07-11 16:34:41

回答

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) 

这种模式将允许你做这样的查询: “什么是informationstuffX

  • “对于stuffY,什么information链接?“
  • ‘查找我要thingZ所有stuffinformation

此外,它可以让你对每个stuff和多stuffinformation每个thing

写下这些问题在开始将帮助您开发准确的模型,而不会在您的数据库中产生不必要的链接/关系

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会很高兴。当然,你应该确定你需要两种关系。在这里使用通用的实体名称看起来可能会有一些混淆。

+0

感谢您的输入。但是,向模型添加'related_name'参数尚未解决问题。 Python仍然说:'ManyToManyField'对象没有'ForeignKey'属性,只有在Stuff模型中同时拥有一个外键和一个ManyToManyField。 – 2012-07-11 16:35:32

+0

你用什么作为'related_names'参数?你可能与django生成的值之一发生冲突。另外:你用的是什么版本的Django? – unayok 2012-07-11 16:58:50

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') 

对不起,我不是很有创造力的名字,这应该工作。

+0

感谢您的输入。但是,向模型添加'related_name'参数尚未解决问题。 Python仍然说:''ManyToManyField'对象没有'ForeignKey'属性,只有在Stuff模型中有*外键和一个ManyToManyField。 – 2012-07-11 16:31:18

+0

@NickB你必须做其他事情因为我发布的例子工作得很好,你必须测试你自己的代码,这可能有另一个问题。 – 2012-07-11 21:27:21