如何在tastypie中为嵌套资源提供正确的URL

时间:2013-09-09 06:09:32

标签: django tastypie

我正在使用来自tastypie的嵌套资源菜谱模式,可以找到here,只有我使用多对多关系。

这意味着前置网址看起来像这样:

class ParentResource(ModelResource):
children = fields.ToManyField(ChildResource, 'children')

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

def get_children(self, request, **kwargs):
    #some way to get the filter
    child_resource = ChildResource()
    return child_resource.get_list(request, parent_id=obj.pk)

这种方法很好,除了分页使用子资源的url而不是prepend__urls中的url。 I.E.而不是:

"meta": {
    "limit": 1,
    "next": "/api/parent/1/childrens?limit=1&offset=1",
    "offset": 0,
    "previous": null,
    "total_count": 2
},

我明白了:

"meta": {
    "limit": 1,
    "next": "/api/parent/?limit=1&offset=1",
    "offset": 0,
    "previous": null,
    "total_count": 2
},

无论如何都要让分页网址正确显示?

2 个答案:

答案 0 :(得分:2)

我修复了以下内容:

  1. 使用&#34; custom_uri&#34;关于子资源的get_list方法的参数。 要做到这一点,你必须重新实现完整的方法:
  2. def get_list(self, request, **kwargs):
        """
        Returns a serialized list of resources.
    
        Calls ``obj_get_list`` to provide the data, then handles that result
        set and serializes it.
    
        Should return a HttpResponse (200 OK).
        """
        # TODO: Uncached for now. Invalidation that works for everyone may be
        #       impossible.
    
        base_bundle = self.build_bundle(request=request)
        objects = self.obj_get_list(bundle=base_bundle, **self.remove_api_resource_names(kwargs))
        sorted_objects = self.apply_sorting(objects, options=request.GET)
    
        if 'custom_uri' in kwargs:
            resource_uri = kwargs['custom_uri']
        else:
            resource_uri = self.get_resource_uri()
    
        paginator = self._meta.paginator_class(request.GET, sorted_objects, resource_uri=resource_uri, limit=self._meta.limit, max_limit=self._meta.max_limit, collection_name=self._meta.collection_name)
        to_be_serialized = paginator.page()
    
        # Dehydrate the bundles in preparation for serialization.
        bundles = []
    
        for obj in to_be_serialized[self._meta.collection_name]:
            bundle = self.build_bundle(obj=obj, request=request)
            bundles.append(self.full_dehydrate(bundle, for_list=True))
    
        to_be_serialized[self._meta.collection_name] = bundles
        to_be_serialized = self.alter_list_data_to_serialize(request, to_be_serialized)
        return self.create_response(request, to_be_serialized)
    
    1. 在父方法上发送正确的uri:
    2. def trip_photos(self, request, **kwargs):
          try:
              bundle = self.build_bundle(data={'pk': kwargs['pk']}, request=request)
              obj = self.cached_obj_get(bundle=bundle, self.remove_api_resource_names(kwargs))
          except ObjectDoesNotExist:
              return HttpGone()
          except MultipleObjectsReturned:
              return HttpMultipleChoices("More than one resource is found at this URI.")
      
          custom_uri = self._build_reverse_url('api_get_children', kwargs=self.resource_uri_kwargs(bundle))
      
          child_resource = ChildResource()
          return child_resource.get_list(request, parent_id=obj.pk, custom_uri=custom_uri)
      

答案 1 :(得分:0)

我认为这是应该改变的近似值。你为什么不让孩子(孩子没有',已经复数;))与ChildResource的父母相关?

http://SERVER/api/v1/child/?parent=1&limit=1&offset=1

然后没有分页问题。