2
我正在爲使用自定義權限處理的現有系統開發REST API。我試圖使用Django REST框架中的內置泛型,但我遇到了使用我的自定義權限過濾列表視圖的麻煩。我當前視圖的一個例子是:使用自定義函數過濾Django查詢集
class WidgetList(generics.ListCreateAPIView):
permission_classes = (permissions.IsAuthenticated,)
model = Widget
serializer_class = WidgetSerializer
filter_backends = (filters.DjangoFilterBackend,)
filter_fields = ('widget_type', 'widget_owner')
def get_queryset(self):
"""
Overwrite the query set to check permissions
"""
qs_list = [w.id for w in self.model.objects.all() if
canReadWidget(self.request.user, w)]
return self.model.objects.filter(id__in=qs_list)
這工作,但我覺得像get_queryset功能可以改善。因爲我的canReadWidget是自定義的,所以我必須評估self.model.objects.all()
並檢查用戶可以讀取哪些小部件,但該函數必須返回一個查詢集,以便使用id__in=qs_list
部分。結果是,我做了兩次數據庫調用,實際上只是一次列表提取。
是否有一種標準的方法來處理這種按通用列表視圖進行的對象過濾?
'canReadWidget'在做什麼?你能發佈代碼嗎? – ilse2005
canReadWidget相當複雜 - 基本上,Widgets存在於樹中,其中一些小部件是另一個小部件類型的子項。用戶可以在樹中的任何級別擁有權限。所以基本上canReadWidget(user,WidgetA)會檢查用戶是否擁有WidgetA的權限,如果是的話它將返回True或False,否則它會查找WidgetA的父級以查看是否有權限繼承,等等直到找到一個或返回false。 –
你可以看看django-guardian的對象權限。但看到你已經實現了你自己的分層權限邏輯,你可能不想切換到新的進程。只要您無法使用SQL連接來制定權限邏輯(通過創建您自己的QueryManager實現或使用自定義過濾器查詢),就無法像現在這樣避免評估和重新獲取。 – Risadinha