2012-11-02 84 views
3

在我的post方法上,我想自動填充當前用戶的'owner'字段(我正在使用BasicAuthentication)。我在這裏跟着一些代碼:How to get authorized user object in django-tastypie - 但我還沒有完全正確地工作。Django Tastypie - 自動獲取當前用戶資源

resources.py:

class QuestionResource(ModelResource): 
    owner = fields.ForeignKey(UserResource, 'owner') 
    class Meta: 
     queryset = Question.objects.all() 
     allowed_methods = ['get','post'] 
     fields = ['title','type'] 
     resource_name = 'question' 
     include_resource_uri = True 
     serializer = PrettyJSONSerializer() 
     authentication = BasicAuthentication() 
     authorization = Authorization() 

    def obj_create(self, bundle, request=None, **kwargs): 
     bundle = self.full_hydrate(bundle, request) 
     return bundle 

    def obj_update(self, bundle, request=None, **kwargs): 
     bundle = self.full_hydrate(bundle, request) 
     return bundle 

    def full_hydrate(self, bundle, request=None): 
     bundle = self.hydrate(bundle, request) 
     return bundle 

    def hydrate(self, bundle, request=None): 
     bundle.obj.owner = User.objects.get(pk = request.user.id) 
     return bundle 

如果我發出以下命令:

curl -u USERNAME:XXXXXXX --dump-header - -H "Accept: application/json" -H "Content-Type: application/json" -X POST --data "{\"title\":\"my new question\",\"type\":\"multichoice\"}" http://localhost/python/mquiz/api/v1/question/ 

我得到的迴應:

HTTP/1.1 201 CREATED 
Date: Fri, 02 Nov 2012 08:28:05 GMT 
Server: Apache/2.2.22 (Ubuntu) 
Vary: Accept-Language,Cookie,Accept-Encoding 
Location: http://localhost/python/mquiz/api/v1/question/None/ 
Content-Language: en-us 
Content-Length: 0 
Content-Type: text/html; charset=utf-8 

所以它看起來好像它所有的工作,但沒有添加到數據庫中,並且位置看起來不正確(最後使用/ None /)。

我確定這是與「bundle.obj.owner = User.objects.get(pk = request.user.id)」行有關。如果我使用「bundle.obj.owner = request.user.id」然後我得到的錯誤:

"error_message": "Cannot assign \"3L\": \"Question.owner\" must be a \"User\" instance." 

至於我可以告訴bundle.obj.owner需要在以下形式:「/ python/mquiz/api/v1/user/3 /' - 如果我在curl請求中使用此參數作爲數據中的所有者參數(並刪除我的自定義水合方法),那麼它一切正常並且被添加到數據庫中。那麼如何將我的用戶實例轉換爲將被接受的形式?

任何幫助非常感謝。

回答

1

當前驗證的答案是次優的,因爲它導致2個SQL查詢。

你還是修改您的查詢集如下:

queryset = Question.objects.select_related('owner').all() 

這樣的「所有者」的數據在一個單獨的SQL查詢加盟。

+0

剛剛更新,使您的接受答案 –

4

啊......現在想通了。什麼工作:

class QuestionResource(ModelResource): 
    owner = fields.ForeignKey(UserResource, 'owner') 
    class Meta: 
     queryset = Question.objects.all() 
     allowed_methods = ['get','post'] 
     fields = ['title','type'] 
     resource_name = 'question' 
     include_resource_uri = True 
     serializer = PrettyJSONSerializer() 
     authentication = BasicAuthentication() 
     authorization = Authorization() 


    def hydrate(self, bundle, request=None): 
     bundle.obj.owner = User.objects.get(pk = bundle.request.user.id) 
     return bundle 

我需要bundle.request.user.id而不僅僅是request.user.id。也許我在看的另一個問題提到了TastyPie的老版本 - 似乎老版本在捆綁中沒有請求可訪問?

+2

感謝您的支持。在TastyPie 0.9.15中沒有'hydrate'的'request'參數,但這仍然有效。另外,你可以將主線縮短爲'bundle.obj.owner = bundle.request.user'。 –