2012-07-11 206 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