如何在脱水后排序在Tastypie中创建所有数据

时间:2016-10-07 00:56:21

标签: django tastypie

我希望BookResource使用dedydrate(...)函数执行join(带有author表的book表)。最终结果应按表作者排序。

为Book表中的每个项调用

dehydrate(...)。

    class Author(Model) 
      author_name = models.CharField(max_length=64)

    class Book(Model)
      author = models.ForeignKey('Author')
      book_name = models.CharField(max_length=64)

    class BookResource(ModelResource):

      class Meta(object):
        # The point here is Book table can be sorted. But, final result 
        # should be sorted by author_name
        queryset = Book.objects.all().order_by('book_name')
        resource_name = 'api_test'
        serializer = Serializer(formats=['xml', 'json'])
        allowed_methods = ('get')
        always_return_data = True

      def dehydrate(self, bundle):
        author_id = bundle.obj.author.id  # author is foreign key of book
        author_obj = Author.objects.get(id=bundle.obj.author.id)
        # Construct queryset with author_name. Same as join 2 tables.
        # But, I want to sort by author.
        bundle.data['author_name'] = author_obj.author_name
        return bundle

      # This is called before dehydrate(...) is called. Not sure how to use it.
      def apply_sorting(self, obj_list, options=None):
        return obj_list

问题:

1)如果使用上面的代码,如何按作者对结果进行排序?

2)无法弄清楚如何加入。你能提供替代方案吗?

谢谢。

1 个答案:

答案 0 :(得分:0)

答案很晚,但是最近我遇到了这个问题。如果您查看dehydrate method上的Tastypie资源 有一系列的方法称为。很快,这是调用的顺序:

  • build_bundle
  • obj_get_list
  • apply_sorting
  • 分页器
  • 全脱水(逐字段)
  • alter_list_data_to_serialize
  • 返回self.create_response

您要关注倒数第二个方法self.alter_list_data_to_serialize(request, to_be_serialized) 基本方法返回第二个参数

    def alter_list_data_to_serialize(self, request, data):
    """
    A hook to alter list data just before it gets serialized & sent to the user.

    Useful for restructuring/renaming aspects of the what's going to be
    sent.

    Should accommodate for a list of objects, generally also including
    meta data.
    """
    return data

无论您想做什么,都可以在这里进行。考虑到要序列化的格式将是一个包含2个字段的命令:meta和objects。对象字段包含捆绑对象列表。

另一个排序层可能是:

    def alter_list_data_to_serialize(self, request, data):
    try:
        sord = True if request.GET.get("sord") == "asc" else False
        data["objects"].sort(
            key=lambda x: x.data[request.GET.get("sidx", default_value)],
            reverse=sord)
    except:
        pass
    return data

您可以优化它,因为有点脏。但这是主要思想。 同样,这是一种解决方法,所有排序都应该属于apply_sorting