更新时的Tastypie错误 - 字段已被赋予不是URI的数据,而不是字典相似且没有'pk'属性

nkn*_*knj 1 api django rest tastypie

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

我想要更新的资源称为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
Run Code Online (Sandbox Code Playgroud)

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
                     }
Run Code Online (Sandbox Code Playgroud)

现在,当我尝试使用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))
Run Code Online (Sandbox Code Playgroud)

但它不起作用!! 救命!

ign*_*aga 5

由于您使用的是PUT方法,因此当您调用obj_update方法时,Tastypie需要在bundle.data对象中使用"account"字段.

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

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

Class MessageResource(ModelResource):
    account = fields.ForeignKey(AccountResource, 'account', full=True,
                                readonly=True)
Run Code Online (Sandbox Code Playgroud)

如果您在创建消息时需要设置帐户,我建议您在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)
Run Code Online (Sandbox Code Playgroud)

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