簡體   English   中英

Django - 根據其內容引用兩個表之一的外鍵

[英]Django - Foreign key referencing one of two tables depending on its content

我在我的數據庫模型設計中遇到了死胡同,可以使用一些幫助。 我們使用 Postgres 數據庫和 django 框架來存儲各種論文、書籍等。

這些是我遇到問題的基類:

class Publisher(models.Model):
    name = models.CharField(unique=True)
    website = models.URLField(blank=True)
    #...

class Editor(models.Model):
    firstname = models.CharField()
    lastname = models.CharField()
    #...

class Book(models.Model):
    title = models.CharField(unique=True)
    #...
    editors = models.ManyToManyField(Editor, blank=True)
    publisher = models.ForeignKey(Publisher, blank=True)
    #...

上面的 Editor 類被建模為將編輯器存儲為相應書籍的人,例如。 “瑞恩·凱里”或“尼古拉斯·羅”。 Publisher 類將包含諸如“芝加哥大學出版社”之類的信息。

問題艙口應該編輯器和出版商是相同的。 例如,編輯和出版商都應該是“芝加哥大學出版社”。

現在,每當通過 django-admin 界面將新書保存到數據庫時,我希望發生以下情況:

  • 如果給出了一個或多個編輯器,則將其保存為上面的模型。
  • 如果沒有給出編輯者但給出了發布者,則使編輯者指向與發布者指向的相同的關鍵
  • 如果兩者都沒有給出,則將兩者都留空

我正在考慮以某種方式實現它:

class Book:
#...
    def save(self, *args, **kwargs):
        if self.editors.count() <= 0 and self.publisher:
            self.editors = self.publisher #This is not possible
        super(Book, self).save(*args, **kwargs)

self.editors = self.publisher 位也許可以通過繼承來修復,但仍然有多個編輯器和只有一個發布者,我不希望發布者和編輯器存儲在同一個表中。

關於如何解決這個問題的任何想法?

幾乎不需要重新構建您的模型,這是可能的,並且比現在更加靈活。

第一:不要將發布者和編輯者置於 2 個不同的模型中。 做一個。

第二:如果您可以同時擁有個人和組織/公司的出版商/編輯器(這將需要不同的模型字段),請將所有常見字段放入一個模型中,並制作 2 個將從該模型繼承的模型,其中包含更多指定的字段。 這將在引擎蓋下創建字段之間的一對一關系。

第三:在您的圖書模型中創建 2 個字段,一個ForeignKey命名為publisher和一個ManyToMany命名為editors 這兩個關系都應該指向您的發布者/編輯者的基本模型。

示例代碼:

class PEBase(models.Model): # have no idea how to name it better

    some_common_field = models.Field(...)


class PEPerson(PEBase):

    first_name = models.CharField()
    last_name = models.CharField()


class PEOrganization(PEBase):

    name = models.CharField()
    website = models.URLField()


class Book(models.Model):

    title = models.CharField(unique=True)
    #...
    editors = models.ManyToManyField(PEBase, blank=True, related_name="books_edited")
    publisher = models.ForeignKey(PEBase, blank=True, related_name="books_published")

    def save(self, *args, **kwargs):
        super(Book, self).save(*args, **kwargs)
        if self.editors.count() <= 0 and self.publisher:
            self.editors.add(self.publisher) #This must go after save - ID of book must be already set.

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM