1

当我尝试更新我的资源时,我不断收到此错误。

我要更新的资源称为 Message。它有一个外键记账:

class AccountResource(ModelResource):
    class Meta:
        queryset = Account.objects.filter()
        resource_name = 'account'
        '''
        set to put because for some weird reason I can't edit 
        the other resources with patch if put is not allowed.
        '''
        allowed_methods = ['put']
        fields = ['id']


    def dehydrate(self, bundle):
        bundle.data['firstname'] = bundle.obj.account.first_name   
        bundle.data['lastname'] = bundle.obj.account.last_name
        return bundle

class MessageResource(ModelResource):
    account = fields.ForeignKey(AccountResource, 'account', full=True)

    class Meta:
        queryset = AccountMessage.objects.filter(isActive=True)
        resource_name = 'message'
        allowed = ['get', 'put', 'patch', 'post']
        authentication = MessageAuthentication()
        authorization = MessageAuthorization()   
        filtering = {
                     'account' : ALL_WITH_RELATIONS
                     }

现在,当我尝试使用 PATCH 更新我的消息时,我收到此错误:

传入的数据{"text":"blah!"}

The 'account' field has was given data that was not a URI, not a dictionary-alike and does not have a 'pk' attribute: <Bundle for obj: '<2> [nikunj]' and with data: '{'lastname': u'', 'id': u'2', 'firstname': u'', 'resource_uri': '/api/v1/account/2/'}'>.

不好的解决方案::

传入数据:{"text":"blah!", "account":{"pk":2}} 我不想传入帐户。我只想编辑文本而不是别的。为什么还需要转帐呢?

我尝试使用:

def obj_update(self, bundle, request=None, **kwargs):
        return super(ChartResource, self).obj_update(bundle, request, account=Account.objects.get(account=request.user))

但它不起作用! 帮助!

4

2 回答 2

6

由于您使用的是 PUT 方法,因此当您调用 obj_update 方法时,Tastypie 需要 bundle.data 对象中的“帐户”字段。

obj_update 中的关键字参数也不像 obj_create那样用于设置值,它们用于搜索有问题的对象。因此,当您传递 account=Account... 关键字参数时,您只是告诉 obj_create 方法在 AccountMessage 表中搜索并按帐户过滤。

解决此问题的一种方法是将只读值设置为 True

Class MessageResource(ModelResource):
    account = fields.ForeignKey(AccountResource, 'account', full=True,
                                readonly=True)

如果您在创建消息时需要设置帐户,我建议在您的 obj_create 方法中设置它

def obj_create(self, bundle, request=None, **kwargs):
    account = Account.objects.get(account=request.user)
    return super(MessageResource,
                 self).obj_create(bundle, request, account=account, **kwargs)

这似乎是一个更好的解决方案,因为根据我从您的代码中可以理解的内容,帐户值指向消息的创建者,因此它应该由系统而不是用户设置。

于 2012-10-27T16:55:41.347 回答
0

尝试使用其中没有 full=True 的资源。Tastypie 对具有 full=True 的资源有一些不同的期望——主要是包括整个记录。我相信这也包括儿童资源。

于 2012-07-13T15:04:41.977 回答