设置字段的来源

时间:2019-04-07 16:44:35

标签: django-rest-framework

使用Django REST Framework,我有以下序列化程序:

class TagSelectOptionsSerializer(serializers.ModelSerializer):
    label = serializers.CharField(source='title')
    value = serializers.IntegerField(source='id')

    class Meta:
        model = Tag
        fields = ('value', 'label')
        read_only_fields = ('value', 'label', )

尝试在我的视图中使用它时(见下文),出现以下错误:

'QuerySet' object has no attribute 'id'

有人可以告诉我如何访问主键字段,就像我正在访问上述序列化程序中的标题字段一样?

class TagSelectOptions(APIView):
    """
    ...
    """

    def get(self, request):
        tags = Tag.objects.filter(approved=True)

        if len(tags) > 1:
            serializer = TagSelectOptionsSerializer(tags, many=True)
        else:
            serializer = TagSelectOptionsSerializer(tags)

        return Response(serializer.data, status=rest_status.HTTP_200_OK)

1 个答案:

答案 0 :(得分:1)

您的get方法不正确。

当结果的长度小于或等于1时,您仍然应该发送many = True。

因为API的行为应保持不变。 JSON方案将在所有情况下返回对象列表。

因此将代码更改为:

def get(self, request):
    tags = Tag.objects.filter(approved=True)
    # handles all cases by default
    serializer = TagSelectOptionsSerializer(tags, many=True)
    return Response(serializer.data, status=rest_status.HTTP_200_OK)

但是,如果您真的想在查询集仅返回单个结果时仅返回单个对象,请使用:

def get(self, request):
    tags = Tag.objects.filter(approved=True)

    if len(tags) == 1:
        serializer = TagSelectOptionsSerializer(tags[0])
    else:
        # when len > 1 or len == 0
        serializer = TagSelectOptionsSerializer(tags, many=True)

    return Response(serializer.data, status=rest_status.HTTP_200_OK)