用相关 objects 扩展 tastypie API
Extending tastypie API with related objects
我是 Django 的新手,Tastypie 在这里提问。
我有一个使用 Tastypie 的 API 的 Django 应用程序。如果我向 /api/v1/ou/33/
发出 GET
请求,我的 API returns id==33 的 object 没问题。
{
"child_ou_uri": "/api/v1/ou/33/child_ou/",
"displayname": "Mother",
"id": 33,
"inherit": true,
"name": "Mother",
"resource_uri": "/api/v1/ou/33/"
}
问题是,我正在尝试扩展 API 以便它 returns 通过上面 [=50] 中的 child_ou_uri
URI 与 object 相关=]. children 与他们的 parents 是同一类型的 objects。该模型有一个属性 parent_id
指向其 parent 的 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/
时,我想获取 child object 的列表,它们的属性 parent_id
设置为 33,但是我获取我所有的 object 完全没有任何过滤,相当于我导航到 /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 更改为如下所示。这使我可以导航到 url,例如 /api/v1/ou/33/child_ous/
,其中 returns 是 child object 的自定义 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)
首先,查看 creating a search 上的 tastypie 文档。
如果不嵌套,这样做会更容易,例如/api/v1/ou_related/?to=58,但为了表现力,可能需要嵌套。
对于带分页的嵌套搜索,请查看创建另一个资源 OuSearchResource。该资源将 override authorized_read_list(可能 get_list)传递必要的详细信息。
我是 Django 的新手,Tastypie 在这里提问。
我有一个使用 Tastypie 的 API 的 Django 应用程序。如果我向 /api/v1/ou/33/
发出 GET
请求,我的 API returns id==33 的 object 没问题。
{
"child_ou_uri": "/api/v1/ou/33/child_ou/",
"displayname": "Mother",
"id": 33,
"inherit": true,
"name": "Mother",
"resource_uri": "/api/v1/ou/33/"
}
问题是,我正在尝试扩展 API 以便它 returns 通过上面 [=50] 中的 child_ou_uri
URI 与 object 相关=]. children 与他们的 parents 是同一类型的 objects。该模型有一个属性 parent_id
指向其 parent 的 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/
时,我想获取 child object 的列表,它们的属性 parent_id
设置为 33,但是我获取我所有的 object 完全没有任何过滤,相当于我导航到 /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 更改为如下所示。这使我可以导航到 url,例如 /api/v1/ou/33/child_ous/
,其中 returns 是 child object 的自定义 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)
首先,查看 creating a search 上的 tastypie 文档。
如果不嵌套,这样做会更容易,例如/api/v1/ou_related/?to=58,但为了表现力,可能需要嵌套。
对于带分页的嵌套搜索,请查看创建另一个资源 OuSearchResource。该资源将 override authorized_read_list(可能 get_list)传递必要的详细信息。