2013-04-15 79 views
0

由於我的模型的自定義save方法將request.user作爲參數,因此我無法執行POST/PUT請求。Django-tastypie將request.user傳遞給自定義保存方法

TypeError at /api/obsadmin/observation/23 
save() takes at least 2 arguments (1 given) 

我正在使用SessionAuthentication()幷包含CSRF令牌。

下面是相關的模型部分:

def save(self, user, owner=None, *args, **kwargs): 
    self.updated_by = user.id 
    super(ObsModel, self).save(*args, **kwargs) 

和資源:

class ObservationResource2(ModelResource): 

comments = fields.ToManyField(CommentResource2, 'comments', full=True, null=True) 

class Meta: 
    queryset = Observation.objects.filter(is_verified=True) 
    authentication = SessionAuthentication() 
    authorization = DjangoAuthorization() 
    resource_name = 'observation' 
    always_return_data = True 

回答

2

你可以重寫你的ModelResource子類的默認save()方法。查看default implementation顯示save()與一個包含請求和要保存的對象的包對象一起被調用。

不幸的是,沒有簡單的方法可以在不復制大部分代碼的情況下進行更改,因爲更改Django模型的save()簽名相當不常見。您也許能夠做這樣的事,但我建議你仔細測試它:

from functools import partial 

try: 
    old_save = bundle.obj.save 
    bundle.obj.save = partial(old_save, user=bundle.request.user) 
    return super(FooResource, self).save(bundle) 
finally: 
    bundle.obj.save = old_save 

參考文獻:

5

我剛剛通過使用內置的hydrate方法在保存之前修改數據,實現了相同的最終目標。目前的請求在hydrate方法內的bundle.request中可用。請參閱文檔here

我有一個Friend模型暴露通過FriendResource,我想鏈接到創建Django用戶通過user ForeignKey字段。

我的示例代碼資源:

class FriendResource(ModelResource): 
    class Meta: 
     queryset = Friend.objects.all() 
     resource_name = 'friend' 
     excludes = ['slug',] 
     authentication = SessionAuthentication() 
     authorization = DjangoAuthorization() 
     always_return_data = True 

    def get_object_list(self, request): 
     return super(FriendResource, self).get_object_list(request).filter(user=request.user) 

    def hydrate(self, bundle): 
     bundle.obj.user = bundle.request.user 
     return bundle 

希望幫助!

+1

我不再使用Tastypie(我們切換到DRF),但感謝您的回答。我相信這對某人會有所幫助。 – ObviousCat

+0

非常感謝!這種機制有點令人困惑,文檔很少,我浪費了一個小時試圖找出答案。 – roboslone

相關問題