簡體   English   中英

如何將外鍵選擇限制為同一模型中的另一個外鍵

[英]How to restrict Foreign Key choices to another Foreign Key in the same model

我正在制作Django應用程序,但遇到了問題。 我正在嘗試定義一個模型,其中一個ForeignKey將依賴於另一個ForeignKey

說明部分

我的申請是關於做出選擇。

假設您有一個decision ,一個decision有多個choice ,一個choice具有status (由於其他限制)。

一個status可以用於多個choices ,但是一個status只能與一個decision相關,該choice鏈接到同一decision

數據庫架構

它不是固定的,可以根據需要進行更改:

,____________,                  ,____________,
|            | 1, n        1, 1 |            |
|  Decision  |------------------|   Status   |
|____________|                  |____________|
      |                                |
      | 1, n                           | 1, n
      |                                |
      | 1, 1                           |
,_____|______,                         |
|            | 1, 1                    |
|   Choice   |-------------------------'
|____________|

這是我當前的(簡體)( 不起作用 )代碼:

class Decision (models.Model):
    name = models.CharField (max_length = 63)

class Status (models.Model):
    value = models.CharField (max_length = 63)
    decision = models.ForeignKey (Decision)

class Choice (models.Model):
    name = models.CharField (max_length = 63)

    decision = models.ForeignKey (Decision)
    status = models.ForeignKey (Status, limit_choices_to = {'decision' : decision})

這里的重要部分是limit_choices_to = {'decision' : decision}

額外信息

我發現了另一個SO問題( 在django中,如何基於同一模型中的另一個字段來限制對Foreignfield的選擇? ),該問題涉及相同的問題,但是這個問題已經過時了,最好的答案是依賴於外部應用程序( django-smart-selects )。

我寧願不必使用外部對象,也無法理解為什么僅使用Django無法解決像3表關系這樣簡單的問題!

如果有人有任何解決方案或建議,請告訴我。

您的要求是不可能的,至少不在您設置的范圍之內(沒有表格,沒有外部庫)。 Choice模型的status字段是外鍵,即兩個表之間的關系…簡單地說,它不涉及過濾本身–它不具有此功能。 這不是django的事情,這是數據庫的事情。 Django ORM與您所想的離數據庫並不遙遠,它很棒,但並不是魔術。

一些可用的解決方案是:

  • 通過過濾查詢集在FormField級別上執行此操作
  • 使用類似django-smart-selects之類的東西(上面做了這件事)
  • 覆蓋模型上的save在其中添加檢查,如果失敗則拋出錯誤
  • status設為屬性,並在設置后對其進行驗證檢查

如果您使用FormField方法以及覆蓋save ,則將受益於您知道無法保存Choice因為它違反了此限制,無論是從用戶端(填寫表單)還是從后端(代碼)在Choice實例上調用.save()

我對Django不熟悉,但是如果您要解決問題的“選擇鏈接到同一選項”部分,可以通過以下方法在數據庫級別完成:

在此處輸入圖片說明

請注意標識關系的用法,因此DecisionId向下遷移到兩個“分支”,並在“底部”合並。 因此,如果一個Choice具有Status ,則它們都必須鏈接到同一Decision

我認為這里需要的是through模型,如下所示:

class Choice (models.Model):
    name = models.CharField (max_length = 63)
    status = models.ForeignKey(Status)
    decision = models.ForeignKey(Decision)

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

class Decision(models.Model):
    name = models.CharField(max_length = 63)
    choices = models.ManyToManyField(Status, through = "Choice")    

這樣,每個決策都有很多選擇,每個選擇只有一個狀態。 您可以執行以下查詢: my_decision.choices.all()my_status.decision_set.all()

我建議您看一下文檔 ,以獲取有關如何通過模型使用的示例

在以下語句中, decision既不是可調用對象也不是models.Q對象:

status = models.ForeignKey (Status, limit_choices_to = {'decision' : decision})

這是一種表示您的數據的方法:

class Decision(models.Model):
    ...

# a status is relevant for only one decision
# there may be more than one Status per Decision.
class Status(Models.Model):
    decision = models.ForeignKey(Decision)

# each choice is linked to one decision and has a status.
class Choice (models.Model):
    status = models.ForeignKey(Status)
    # if status is mandatory, then you can get the decision
    # from status.decision. per se, this fk could be optional.
    decision = models.ForeignKey(Decision)

這是另一個:

class Decision(models.Model):
    ...

# a decision has multiple choices
# a choice pertains to only one decision
class Choice (models.Model):
    decision = models.ForeignKey(Decision)

# each status is relevant to one decision
# and may encompass multiple choices.
class Status(Models.Model):
    decision = models.ForeignKey(Decision)
    # problem with this representation is that this allows for
    # a choice to be linked to multiple statuses.
    # this happens when using M2M instead of ForeignKey.
    choices = models.ManyToManyField(Choice)

暫無
暫無

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

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