Django Tastypie - 自动获取当前用户资源
在我的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请求中使用此参数作为数据中的所有者参数(并删除我的自定义水合方法),那么它一切正常并且被添加到数据库中。那么如何将我的用户实例转换为将被接受的形式?
任何帮助非常感谢。
当前验证的答案是次优的,因为它导致2个SQL查询。
你还是修改您的查询集如下:
queryset = Question.objects.select_related('owner').all()
这样的“所有者”的数据在一个单独的SQL查询加盟。
啊......现在想通了。什么工作:
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的老版本 - 似乎老版本在捆绑中没有请求可访问?
感谢您的支持。在TastyPie 0.9.15中没有'hydrate'的'request'参数,但这仍然有效。另外,你可以将主线缩短为'bundle.obj.owner = bundle.request.user'。 –
刚刚更新,使您的接受答案 –