Tastypie嵌套资源 - cached_obj_get()需要2个参数(给定1个)

7 投票
1 回答
1864 浏览
提问于 2025-04-17 17:34

我正在尝试使用这里的示例:http://django-tastypie.readthedocs.org/en/latest/cookbook.html#nested-resources

但不知为什么,我遇到了这个错误:

cached_obj_get() 需要两个参数(我只给了一个)

尽管我明明是用两个参数来调用它的(和上面提到的示例完全一样)。这是我的代码:

def prepend_urls(self):
    return [
        url(r"^(?P<resource_name>%s)/(?P<pk>\w[\w/-]*)/feed%s$" % (self._meta.resource_name, trailing_slash()), self.wrap_view('get_feed'), name="api_get_feed"),
]

def get_feed(self, request, **kwargs):
    try:
        obj = self.cached_obj_get(request=request, **self.remove_api_resource_names(kwargs)) 
    except ObjectDoesNotExist:
        return HttpGone()
    except MultipleObjectsReturned:
        return HttpMultipleChoices("More than one resource is found at this URI.")

    feed_resource = FeedItemResource()
    return feed_resource.get_list(request, p_id=obj.id)

1 个回答

14

抱歉让你感到困惑——最近有一个API的改动是为了改善授权,这导致了cached_obj_get的使用方式发生了变化,从:

def cached_obj_get(self, request=None, **kwargs):

变成了

def cached_obj_get(self, bundle, **kwargs):

这个改动是为了让后续的使用更加一致——如果你需要使用request对象,它现在可以通过bundle.request来获取——但显然文档需要更新一下。

你可以通过以下方式构建一个bundle对象:

basic_bundle = self.build_bundle(request=request)

然后把它作为参数传给cached_obj_get(可以参考Resource.get_detail的源代码作为例子):

obj = self.cached_obj_get(bundle=basic_bundle, **self.remove_api_resource_names(kwargs))

如果你对Python的对象模型不太熟悉,可能会觉得另一个地方也有点困惑,那就是方法总是至少需要一个参数,因为第一个位置参数总是指向对象实例,也就是self,而关键字参数不算在这个数量里,所以“给了1个”意味着这个方法只收到了self这个位置参数,而它其实是期待selfbundle两个参数的。

撰写回答