2015-08-03 35 views
2

關於上下文,這裏是一個菜單系統。Django 1.8:如何確保模型中的兩個域,至少一個或唯一一個必須符合條件?

class Menu(models.Model): 
    ... 


class Link(models.Model): 
    ... 


class MenuItem(models.Model): 
    menu = models.ForeignKey(Menu) 
    submenu = models.ForeignKey(Menu, related_name='submenu', blank=True, null=True) 
    link = models.ForeignKey(Link, blank=True, null=True) 
    position = models.IntegerField() 

我有兩個結果我在尋找實現:

  • 至少一個子菜單和鏈接不能爲空(子菜單標題可以有一個鏈接)
  • 只有一個子菜單和鏈接必須爲空(子菜單標題不能有鏈接)

任何高級驗證對我來說都是新的,因此代碼示例會非常有幫助。

在這個例子中,數據將僅通過Django管理

+0

我沒有試過這個,所以我不會讓它成爲答案,但也許你可以使用多表繼承?如果你同時使'Menu'和'Link'子類爲'MenuItem',那麼'MenuItem'將有兩個一對一關係,其中只有一個非空。 – Duncan

+0

謝謝,這聽起來像獲得第二個結果的潛在方式,但不會覆蓋第一個結果。 – StringsOnFire

回答

3

加入圍繞模型驗證該文檔是很差。有很多(封閉的)問題涉及它,但它仍然不清楚。

此解決方案,而無需更改任何形式:

class MenuItem(models.Model): 
    ... 

    def clean(self): 
     super(MenuItem, self).clean() 
     if self.submenu is None and self.link is None: 
      raise ValidationError('Validation error text') 

clean()有一些默認的驗證功能,所以屬於模型需要清潔先調用。

以上確保至少使用了兩個字段中的一個字段,如果不是,則引發異常。我只在Admin界面中進行了測試。

我不知道這是否是正確的方法來做到這一點,並希望知道更多的人是否有更好的理解Django中的模型驗證。來自其他語言和框架,這感覺就像寫自定義驗證的自然方式。

相關問題