使用相关对象扩展tastypie API

时间:2018-04-23 12:34:44

标签: python django tastypie

我是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)

1 个答案:

答案 0 :(得分:0)

首先,查看creating a search上的tastypie文档。

在没有嵌套的情况下更容易做到这一点,例如/ api / v1 / ou_related /?to = 58,但嵌套可能需要它的表现力。

对于带有分页的嵌套搜索,请查看创建另一个资源OuSearchResource。该资源将override authorized_read_list(可能是get_list)传递必要的细节。