問題是概念性的(數(shù)據(jù)庫關(guān)系),因此語言不是這里的重點,但我正在使用 Python 和 Django。我有 3 個模型/桌子:公司顧客地址例如。class Company(models.Model): name = models.CharField(max_lenght=100) #exampleclass Customer(models.Model): name = models.CharField(max_lenght=100) #exampleclass Adress(models.Model): country = models.CharField(max_lenght=100) #example state = models.CharField(max_lenght=100) #example # here I want the address owner # I could put something like this: company = models.ForeignKey(Company, on_delete=models.PROTECT) customer = models.ForeignKey(Customer, on_delete=models.PROTECT)我希望該地址屬于客戶或公司,但不能同時屬于兩者。我知道我可以簡單地創(chuàng)建 2 個地址類,例如 CustomerAddress、CompanyAddress,每個類都有其正確的外鍵:class Company(models.Model): name = models.CharField(max_lenght=100) #exampleclass Customer(models.Model): name = models.CharField(max_lenght=100) #exampleclass CompanyAdress(models.Model): country = models.CharField(max_lenght=100) #example state = models.CharField(max_lenght=100) #example company = models.ForeignKey(Company, on_delete=models.PROTECT)class CustomerAdress(models.Model): country = models.CharField(max_lenght=100) #example state = models.CharField(max_lenght=100) #example customer = models.ForeignKey(Company, on_delete=models.PROTECT)但我不想這么做,原因有兩個:重復(fù)的代碼以及在 Django 管理面板中我將有兩個單獨的地址列表的事實,這沒有多大意義,因為所有地址在結(jié)構(gòu)上都是相同的。我可以修復(fù)創(chuàng)建基類、繼承基類等的重復(fù)代碼,但我在管理面板中仍然會有 2 個列表。將來我可能會遇到同樣的概念性問題,但會更加復(fù)雜,例如,某些事物有 300 個類,而 1 個類應(yīng)該只有 300 個類中的一個具有外鍵。我應(yīng)該怎么辦?
2 回答

牧羊人nacy
TA貢獻(xiàn)1862條經(jīng)驗 獲得超7個贊
您可以嘗試將外鍵設(shè)置為 null=True 并根據(jù)需要通過視圖控制數(shù)據(jù)庫中的輸入:
class Address(models.Model): country = models.CharField(max_lenght=100) state = models.CharField(max_lenght=100) company = models.ForeignKey(Company, on_delete=models.PROTECT, null=True) customer = models.ForeignKey(Customer, on_delete=models.PROTECT, null=True)

千萬里不及你
TA貢獻(xiàn)1784條經(jīng)驗 獲得超9個贊
下面是一個DB模型。
--?Address?ADR?exists. -- address?{ADR} ?????PK?{ADR}
Party
是個人或組織的通用術(shù)語;判別器TYP
用于區(qū)分兩者。
--?Party?PTY,?of?party-type?TYP,?resides?at?address?ADR. -- party?{PTY,?TYP,?ADR} ???PK?{PTY} ???SK?{PTY,?TYP} CHECK?TYP?in?{'P',?'O'} FK?{ADR}?REFERENCES?address?{ADR}
--?Person,?a?party?PTY?of?party-type?TYP?=?'P',?exists. -- person?{PTY,?TYP} ????PK?{PTY} CHECK?TYP?=?'P' FK?{PTY,?TYP}?REFERENCES?party?{PTY,?TYP}
--?Organization,?a?party?PTY?of?party-type?TYP?=?'O',?exists. -- organization?{PTY,?TYP} ??????????PK?{PTY} CHECK?TYP?=?'O' FK?{PTY,?TYP}?REFERENCES?party?{PTY,?TYP}
筆記:
All?attributes?(columns)?NOT?NULL PK?=?Primary?Key AK?=?Alternate?Key???(Unique) SK?=?Proper?Superkey?(Unique) FK?=?Foreign?Key
關(guān)于亞型的一句話。實現(xiàn)子類型約束的正確方法是使用斷言(CREATE ASSERTION
),但它在主要數(shù)據(jù)庫中仍然不可用。我正在使用FKs
它,并且與所有其他替代方法一樣,它并不完美。人們爭論很多,關(guān)于SO和SE-DBA,哪個更好。我鼓勵您也檢查其他方法。
添加回答
舉報
0/150
提交
取消