Django - 如何在序列化的QuerySet中包含注释结果?

13 投票
4 回答
6829 浏览
提问于 2025-04-18 17:54

如何在序列化的查询集中包含注释结果?

data = serializer.serialize(Books.objects.filter(publisher__id=id).annotate(num_books=Count('related_books')), use_natural_keys=True)

不过,键值对 {'num_books': number} 并没有包含在 json 结果中。

我在网上搜索了类似的问题,但没有找到适合我的解决方案。

这里有一个类似的案例: http://python.6.x6.nabble.com/How-can-you-include-annotated-results-in-a-serialized-QuerySet-td67238.html

谢谢!

4 个回答

-1

要从特定的列中获取数量,你必须通过 values 方法来声明这些列。

>>>> Books.objects.filter(publisher__id=id).values('<group by field>').annotate(num_books=Count('related_books'))
[{'num_books': 1, '<group by field>': X}]
1

根据这个链接,这个问题几个月前通过一个拉取请求解决了,具体可以查看这个链接

你需要把 num_books 加入作为一个属性:

class Publisher():
    ....

    @property
    def num_books(self):
        return some_way_to_count('related_books')

然后像这样调用它:

data = serializer.serialize(Books.objects.filter(publisher__id=id)), use_natural_keys=True, extra=['num_books'])

我对具体的语法不是很确定,因为我不太常用序列化器。

10

这篇帖子中提到,你可以在你的序列化器里使用SerializerMethodField:

class BooksSerializer(serializers.ModelSerializer):

  num_books = serializers.SerializerMethodField()

  def get_num_books(self, obj):
    try:
        return obj.num_books
    except:
        return None

它会把标注的值进行序列化(只读)。

13

我做了一些研究,发现 serializer.serialize 只能对查询集(queryset)进行序列化,而注解(annotation)只是给查询集中的每个对象添加一个属性。因此,当你尝试序列化一个查询时,注解的字段是不会显示出来的。这是我实现的方式:

from django.core.serializers.json import DjangoJSONEncoder

books = Books.objects.filter(publisher__id=id).annotate(num_books=Count('related_books')).values()
json_data = json.dumps(list(books), cls=DjangoJSONEncoder)

撰写回答