如何覆蓋多個ViewSet的POST,PATCH & DELETE方法以允許我添加強制後端參數?覆蓋POST,PATCH和DELETE方法
邏輯。我正在構建一個在所有相關表格中都有「tenant_id」的多租戶應用程序。 tenant_id標識租戶,因此所有請求都必須包含該父密鑰,以避免用戶查看/修改不屬於他們的內容。
對於獲取查詢,我創建了一個自定義過濾器後端使我加一個強制性的過濾器對象來限制用戶可以得到
class CustomFilterBackend(filters.BaseFilterBackend):
"""
Filter that only allows users to see entries related to their tenant.
"""
def filter_queryset(self, request, queryset, view):
tenant_id = get_tenant_id_from_token(request)
return queryset.filter(is_deleted=False, tenant_id=tenant_id)
我已經然後通過加入這個過濾器將所有視圖集中班filter_backends =()
選項
問題是,有沒有辦法實現相同的POST,PATCH,DELETE請求?
我目前的想法是,你會覆蓋所有模型的model.save
方法?但是這不會照顧HTTP DELETE
方法。
透明tenant_id:
在模型中,tenant_id當然是強制性的。但是,我不想強制Web /移動客戶端始終提供tenant_id,因爲我可以從用戶的JWT令牌中獲取它。即tenant_id應該對Web /移動應用程序透明。
EDIT 2
的問題是,我想默默地/悄然/幕後的添加tenant_id
沒有網絡/移動應用程序意識到。這意味着我不希望使用API的應用發送tenant_id
JSON密鑰。
標本模型
class SampleModel(models.Model):
"""
Sample model
"""
title = models.CharField(max_length=100)
tenant = models.ForeignKey(Tenant, on_delete=models.PROTECT)
class CustomFilterBackend(filters.BaseFilterBackend):
"""
Filter that only allows users to see entries related to their tenant.
"""
def filter_queryset(self, request, queryset, view):
tenant_id = get_tenant_id_from_token(request)
return queryset.filter(is_deleted=False, tenant_id=tenant_id)
class SampleViewSet(ListCreateRetrieveUpdateViewSet):
"""
Sample viewset
"""
serializer_class = SampleModelSerializer
permission_classes = (HasPermission)
queryset = SampleModel.objects.all()
filter_backends = (CustomFilterBackend,)
通過添加filter_backends所有viewsets,所有的GET查詢現在包括tenant_id。所以我想要的是實現相同的所有其他HTTP方法,特別是POST和PATCH
從閱讀它似乎我必須重寫序列化器?是否可以以乾式方式進行?到目前爲止,我還沒有想出如何
的智威湯遜在那裏我得到tenant_id有一個有效載荷看起來像這樣創建自定義jwt_payload_handler
後:如果您正試圖找出如何的標識
{
"exp": 1477069682,
"is_superuser": true,
"email": "[email protected]",
"tenant_id": 1, #THE TENANT ID
"user_id": 1,
"username": "[email protected]"
}
我正在使用Django的身份驗證。另外,'ForeignKey'沒有使用'_id'聲明,並且我修正了我給出的示例模型。在你的建議中,我會在哪裏放置'CurrentTenantDefault'?此外,租戶標識符將從JWT令牌的專用部分獲取。我正在使用'django-rest-framework-jwt'並在登錄時將tenant_id添加到了令牌中。查看我添加到問題中的示例.. – lukik
我通常將它保存在'serializers'模塊中,或者當串行器被分割爲幾個模塊時,就像'serializers.core'。我用'get_tenant_id_from_token'函數以'CurrentTenantDefault'爲例更新了答案。 –
謝謝先生。這按預期工作,並且易於理解 – lukik