2009-12-03 29 views
1

我有一個Django應用程序,它有一個單一帳戶模型。我們正在將其轉換爲多帳戶,因此幾乎每個型號都會有一個ForeignKey(Account)如何在Django中實施基於帳戶的分隔

確保每個Account(每個帳戶都在其自己的子域中)只能訪問自己的數據的最簡單方法是什麼?我們有一箇中間件,用於填充子域以及每個請求上的當前帳戶。

我們可以通過在我們所有的觀點中加入filter(...., account = request.account)來實現這一點。這不是希望的,因爲,

  1. filter(...., account = request.account)將被添加到的查詢的所有,使得該非幹,但卻難免重複,容易出錯。
  2. 更大的風險是如果缺少過濾器,則存在安全風險。

回答

2

我不認爲有明確的贏家,特別是如果你考慮到並不是所有的查詢都需要按帳戶過濾。另外考慮舊的threadlocals技巧被認爲是不可靠的,這意味着自動插入濾波器參數的唯一方法是使用中間件,我猜...但對我而言,這似乎也不可靠和複雜。

我還沒有想出一個好的方法來使查詢管理器可以在這裏幫助,但它可能是可能的。

因此,我認爲「多租戶」數據庫的最佳解決方案就是確保您的所有查詢都是按帳戶過濾的。你可以這樣做:

  • 調試模式的中間件如Middleware: Record ownership screener

  • 在您的測試檢查任何測試生成的SQL和驗證帳戶字段查詢。您還可以在測試裝置中包含「其他帳戶」數據,以確保您的測試不會顯示在任何查詢結果中。

  • 確保所有查詢都在代碼審查檢查過濾器

當然不是很漂亮,但最好的我已經能夠到目前爲止做的。

0

This snippet可能會讓你在正確的方向。我相信行級別權限也在1.2的待辦事項列表上,但不是100%確定。

0

是否有一個巨大的原因,你爲什麼不能寫一個函數,自動插入會話帳戶到查詢中,並將所有其他參數作爲參數?

+2

你怎麼會得到'在模型或經理request.session'沒有明確每個查詢的傳遞。如果我按照這種方式行事,我可能會在每次通話時都「過濾」。 – agiliq 2009-12-04 03:03:51

0

你使用的是django.contrib.auth

如果你是,只要賬戶一ForeignKey(User, unique=true)和用戶

即指向所有模型。 ForeignKey(User)

而且,看看在django Auth Docs

編輯:我想我明白你的關心一點現在好了......

而不是做

my_model.objects.filter(user=request.user) 

只是做的:

request.user.my_model_set.all() 
+2

是的,但這仍然意味着,我需要在每個地方放置一個明確的「過濾器」。 – agiliq 2009-12-04 03:02:37

+0

但你可以從用戶對象開始:'user.object1_set.all()'而不是'object1.objects.filter(user = user)' – Jiaaro 2009-12-04 20:07:34