如何从枚举返回标准Django Rest Framework JSON?

jbose2ul  于 2023-02-20  发布在  Go
关注(0)|答案(1)|浏览(151)

我不是很熟悉DRF,我还没有在谷歌上找到这个问题的解决方案(大多数答案是关于一个字段为枚举的模型,我的问题是不同的)
你看,我们在Django应用中有一个枚举,我们称之为SomeValuesEnum。

class SomeValuesEnum(Enum):
    ONE_VALUE = "One value"
    ANOTHER_VALUE = "Another value"

我需要做的是创建一个返回以下内容的GET端点

{
 "count": 2,
 "page_count": 1,
 "next": null,
 "previous": null,
 "results": [
  {
      "value": "One value",
      "name": "ONE_VALUE"
    }, {
      "value": "Another value",
      "name": "ANOTHER_VALUE"
    }
 ]
}

我知道我需要创建一个序列化器,但是我还没有能够创建一个序列化器并“馈送它”。
例如,我从这样的东西开始:

class SomeValueSerializer(serializers.Serializer):
    Meta:
        model = SomeValuesEnum,
        fields = '__all__'

在视图上:

class SomeValueListView(APIView):
    serializer_class = SomeValueSerializer

    def get(self, request):
        choices = [{"value": target.value, "name": target.value.capitalize()} for target in SomeValuesEnum]
        serializer = SomeValueSerializer(data=choices)
        return Response(status=status.HTTP_200_OK, data=serializer.data)

我也试过这个

class IncidentSerializer(serializers.Serializer):
    name = serializers.CharField(required=False, allow_blank=True, max_length=100)
    value = serializers.CharField(required=False, allow_blank=True, max_length=100)

我不确定是创建序列化程序失败了,还是在视图上调用它的方式失败了(或者两者都失败了)
任何正确方向的指导都将不胜感激.

xlpyo6sf

xlpyo6sf1#

枚举不是django模型,你可以为非模型的东西使用DRF序列化器,但是你不应该给予它一个非模型的东西的模型字段。
请参见此处:声明序列化程序
不在此处:模型序列化程序
此外,您将在此处创建基于类的视图:

SomeValueListView(APIView)

你不一定需要这个,你可以使用一个基于函数的视图,如果你是DRF的新手的话,它可能更容易理解。我只是说基于函数的视图更容易理解,因为没有那么多内置的功能。这可以让DRF的新手更容易调试。你仍然可以通过在视图中直接调用它来使用串行化器。
请参见此处:基于功能的视图和此处:序列化对象
最后......给定以下代码:

choices = [{"value": target.value, "name": target.value.capitalize()} for target in SomeValuesEnum]

我假设可能有多个不同的对象进入这个序列化器,假设你使用列表解析。要么你需要为数组中的每个对象单独调用序列化器,要么你用(many=True)调用序列化器。非常肯定这是你的主要问题。如下所示:

serializer = SomeValueSerializer(data=choices, many=True)

请参阅此处:处理多个对象
另外,根据我的经验,最好在序列化器本身内部而不是在视图中解析传入序列化器的数据。对我来说,这是一个关注点分离的问题,但其他人可能会有不同的感觉。这看起来像这样:

class SomeValueListView(APIView):
    serializer_class = SomeValueSerializer

    def get(self, request):
        serializer = SomeValueSerializer(data=SomeValuesEnum)
        return Response(status=status.HTTP_200_OK, data=serializer.data)

class SomeValueSerializer(serializer.Serializer):
    def to_internal_value(self, data)
        name = data.value.capitalize()
        value = data.value
        return {
            'name': name,
            'value: value,
        }

相关问题