Skip to main content
 首页 » 编程设计

python之Django 1.11 订单结果问题之注释计数返回错误值

2024年09月03日35Renyi-Fan

我正在使用 django 1.11:

  • 我有一个模型定义,可以计算外键属性上错误值的数量,如下所示:

型号:

class Model(models.Model): 
    . 
    .  
    .  
 
    def count_total(self): 
        return self.anothermodel_set.filter(val=False).count() 

查看:

class ModelViewSet(viewsets.ReadOnlyModelViewSet): 
    queryset = Model.objects.all() 
    serializer_class = ModelSerializerClass 
    permissions = AuthenticatedReadOnly 
    pagination_class = StandardResultsSetPagination 
 
    def list(self, request): 
        queryset = self.get_queryset() 
 
        # Other annotations... 
 
        # Attempt 1: returns wrong count 
        queryset = queryset.annotate( 
            a_count=Count( 
                Case( 
                    When(anothermodel__val=False, then=1),  
                    default=0,  
                    output_field=IntegerField() 
                ) 
            ) 
        ) 
 
        # Attempt 2: returns wrong count, same as attempt 1 
        queryset = queryset.annotate( 
            b_count=Count(Q(anothermodel__val=False)) 
        ) 
 
        # Ideally I want to do  
        queryset = queryset.order_by('count_total') 

当我按 count_total 进行排序时,我会给出

FieldError at /api/endpoint/ Cannot resolve keyword 'count_total' into field.

因为 count_total 是一个模型定义。

序列化器:

在我的序列化程序中,我修改了 to_represantation 定义以进行调试:

def to_representation(self, instance): 
    return {'id': instance.pk, 'a_count': instance.a_count, 'b_count' : instance.b_count, 'correct_count': instance.count_total()} 

否则在我的序列化程序中我有:

class Meta: 
    model = Model 
    fields = ('id', 'title', 'bunch-of-other-stuff', 'count_total') 

instance.count_total() 返回正确的结果,但我不能简单地将它用作 queryset.order_by('count_total')。我需要注释正确的值以便对结果进行排序并避免 n+1 查询问题。

请您参考如下方法:

我不确定这是否是您的问题,但模型定义似乎未使用,因为您没有返回值,只是在进行计算。应该是:

def count_total(self): 
        return self.anothermodel_set.filter(val=False).count() 

我也很困惑为什么您会在模型和 View 中进行计算。使用模型定义或注释您的查询集,但您不需要同时执行这两项操作。如果你走模型定义路线,你的 View 应该看起来像这样:

class ModelViewSet(viewsets.ReadOnlyModelViewSet): 
    queryset = Model.objects.all() 
    serializer_class = ModelSerializer 
    permissions = AuthenticatedReadOnly 
    pagination_class = StandardResultsSetPagination 
 
    def list(self, request): 
 
        queryset = self.queryset.order_by('count_total') 
        serializer = self.get_serializer(queryset, many=True) 
 
        return Response(serializer.data) 

如果您使用模型定义,您需要在序列化程序中设置类似 read_only 的属性:

count_total = serializers.ReadOnlyField(allow_null=True) 
 
class Meta: 
    model = Model 
    fields = ('id', 'title', 'bunch-of-other-stuff', 'count_total') 

如果您仍然遇到“无法将计数总计解析为字段”错误,请在像这样运行序列化程序之前将打印语句扔到 View 集中:

print(str(queryset)) 

问题可能在于您如何过滤模型定义。