Django/Tastypie中忽略注释

Mar*_*rio 7 django annotations tastypie

在我的Tastypie资源中,我正在注释我的查询集,但我没有看到注释流向JSON Tastypie生成并传回.代码很简单:

class CompetitionResource(ModelResource):
    total_tickets = fields.IntegerField(readonly=True)

    class Meta:
        queryset = Competition.objects.all().annotate(total_tickets=Count('ticket__ticketownership__user__id', distinct=True))
Run Code Online (Sandbox Code Playgroud)

我在我的查询集中生成和注释的Count只是没有显示在最终的JSON中.最终的JSON有一个total_users字段(因为我在ModelResource中声明了一个),但它是null.我是否遗漏了任何明显的东西以确保这样的注释得以通过?如果没有,那么解决这个问题的方法是什么?

一种方法是在我的Model中创建一个属性,然后将ModelResource中的total_users字段绑定到该属性.但这可能会导致我从数据库中抽取的每个竞赛的Count查询,这并不好.我想在一个注释类型查询中执行此操作.

Mar*_*rio 5

好,我知道了.您可以简单地使用可添加到ModelResource的自定义dehydrate_ [字段名称]方法.对于每个ModelResource字段,Tastypie检查是否指定了dehydrate_ [字段名称]方法,如果你没有,则它当它处理的对象成束(其随后被放出来作为JSON或XML或其他)调用该方法.对于该特定对象,此dehydrate_ [field name]方法获取Tastypie为此之前创建的包.好处是这个bundle在bundle.obj下有原始对象.该对象仍将具有您在get_object_list中提供的原始注释(如上面的答案所示).所以你可以使用以下代码.

class CompetitionResource(ModelResource):
    total_tickets = fields.IntegerField(readonly=True)

    class Meta:
        queryset = Competition.objects.all()

    def get_object_list(self, request):
        return super(CompetitionResource, self).get_object_list(request).annotate(total_tickets=Count('ticket__ticketownership__user__id', distinct=True))

    def dehydrate_total_tickets(self, bundle):
        return bundle.obj.total_tickets
Run Code Online (Sandbox Code Playgroud)

无论您从自定义的dehydrate_ [field name]方法返回什么,都将正确存储为该字段在该对象的包中的最终值,然后正确处理为输出.