我是Django,Tastypie的新手并在这里提问。
我有一个使用Tastypie的API的Django应用程序。如果我向GET
发出/api/v1/ou/33/
请求,我的API会返回ID == 33的对象,这是正常的。
{
"child_ou_uri": "/api/v1/ou/33/child_ou/",
"displayname": "Mother",
"id": 33,
"inherit": true,
"name": "Mother",
"resource_uri": "/api/v1/ou/33/"
}
问题是,我正在尝试扩展API,以便它通过上述对象的child_ou_uri
URI返回相关对象。孩子与父母是同一类型的对象。该模型的属性parent_id
指向其父级的pk
。
我的OuResource
看起来像这样:
class OuResource(ModelResource):
class Meta:
queryset = OU.objects.all()
resource_name = 'ou'
list_allowed_methods = ['get']
detail_allowed_methods = ['get']
filtering = {
'name': ['icontains'],
}
authentication = SessionAuthentication()
authorization = OperatorLocationAuthorization()
def get_child_ou(self, request, **kwargs):
self.method_check(request, ['get', ])
ous = OuResource().get_list(request, parent_id=kwargs['pk'])
return ous
def prepend_urls(self):
return [
url(r'^(?P<resource_name>%s)/(?P<pk>\w[\w/-]*)/child_ou%s$' % (self._meta.resource_name, '/'),
self.wrap_view('get_child_ou'),
name='api_get_child_ou')
]
def dehydrate(self, bundle):
kwargs = dict(api_name='v1', resource_name=self._meta.resource_name, pk=bundle.data['id'])
bundle.data['child_ou_uri'] = reverse('api_get_child_ou', kwargs=kwargs)
return bundle
当我导航到/api/v1/ou/33/child_ou/
时,我想获取属性parent_id
设置为33的子对象列表,但我得到的所有对象都没有任何过滤,相当于我导航到/api/v1/ou/
。
{
"meta": {
"limit": 20,
"next": "/api/v1/ou/?offset=20&limit=20&format=json",
"offset": 0,
"previous": null,
"total_count": 29
},
"objects": [
{
"child_ou_uri": "/api/v1/ou/33/child_ou/",
"displayname": "Mother",
"id": 33,
"inherit": true,
"name": "Mother",
"resource_uri": "/api/v1/ou/33/"
},
{
"child_ou_uri": "/api/v1/ou/57/child_ou/",
"displayname": "Mothers 1st child",
"id": 57,
"inherit": true,
"name": "Child 1",
"resource_uri": "/api/v1/ou/57/"
},
{
"child_ou_uri": "/api/v1/ou/58/child_ou/",
"displayname": "Mothers 2nd child",
"id": 58,
"inherit": true,
"name": "Child 2",
"resource_uri": "/api/v1/ou/58/"
}
]
}
我在这里缺少什么?
[溶液]
Gareth的回答让我走上正轨。我把我的OuResource改成了如下所示。这允许我导航到像/api/v1/ou/33/child_ous/
这样的URL,它返回子对象的自定义json。
class OuResource(ModelResource):
class Meta:
queryset = OU.objects.all()
resource_name = 'ou'
list_allowed_methods = ['get']
detail_allowed_methods = ['get']
filtering = {
'name': ['icontains'],
}
authentication = SessionAuthentication()
authorization = OperatorLocationAuthorization()
def prepend_urls(self):
return [
url(r"^(?P<resource_name>%s)/(?P<ou_id>\d+)/child_ous%s$" % (self._meta.resource_name, trailing_slash()), self.wrap_view('child_ous'), name="api_child_ous"),
]
def child_ous(self, request, **kwargs):
self.method_check(request, allowed=['get'])
self.is_authenticated(request)
self.throttle_check(request)
ous = list(OU.objects.filter(parent_id=kwargs['ou_id']))
data = []
for x in ous:
data.append({
'id' : x.id,
'name' : x.name,
'parent_id' : x.parent_id
})
return JsonResponse(data, safe=False)
答案 0 :(得分:0)
首先,查看creating a search上的tastypie文档。
在没有嵌套的情况下更容易做到这一点,例如/ api / v1 / ou_related /?to = 58,但嵌套可能需要它的表现力。
对于带有分页的嵌套搜索,请查看创建另一个资源OuSearchResource。该资源将override authorized_read_list(可能是get_list)传递必要的细节。