我有一個需要受到它們保護的權限檢查和視圖的層次結構。例如,考慮這兩個檢查。撰寫適用於基於類的視圖的修飾器
def has_profile(user):
return user.profile is not None
def is_a_sorcerer(user):
return user.profile.category == 'sorcerer'
請注意,只有在用戶具有配置文件時調用is_a_sorcerer
纔有意義。
對於任何有個人檔案的人來說,一些視圖應該是可以訪問的,一些視圖只能限制在巫師身上。
class ProfileView(View):
@method_decorator(user_passes_test(has_profile))
def dispatch(self, *args, **kwargs):
return super().dispatch(*args, **kwargs)
class SorcererView(ProfileView):
@method_decorator(user_passes_test(is_a_sorcerer))
def dispatch(self, *args, **kwargs):
return super().dispatch(*args, **kwargs)
但是,請注意,由於繼承,is_a_sorcerer
將has_profile
之前調用和錯誤的。
有可能在is_a_sorcerer
檢查has_profile
:
def is_a_sorcerer(user):
return has_profile(user) and user.profile.category == 'sorcerer'
雖然這修正錯誤,會導致檢查has_profile
兩次,有兩個以上的級別檢查的開銷迅速積累。
如何在不重複代碼的情況下編寫這些裝飾器?我仍然希望將權限檢查保留爲函數,以便可以將它們應用於基於函數的視圖。
該繼承的問題是什麼?如果用戶沒有配置文件,它不能成爲魔術師,可以嗎? 在'is_a_sorcerer'實現中,你應該檢查'has_profile'是否也是。 – afilardo
使用[權限](https://docs.djangoproject.com/zh/1.10/topics/auth/customizing/#custom-permissions)不是一個選項嗎? – afilardo
將'permission_required'裝飾器添加到視圖與'user_passes_test'不會有區別,並且仍然需要兩次檢查權限。 – Koterpillar