python 问题初始化django串行化器与额外的变量是用在选择字段

guz6ccqo  于 2022-12-28  发布在  Python
关注(0)|答案(1)|浏览(118)

我有一个这样的django序列化器

# urls
urlpatterns = [
    path("cat", CatView.as_view(), name="cat")
]
# serializers
class CatSerializer(serializers.Serializer):
    name = serializers.ChoiceField(choices=[])

    def __init__(self, *args, **kwargs):
        self.names = kwargs.pop("names")
        self.fields["name"].choices = self.names

        super().__init__(self, *args, **kwargs)
# views
class CatView(APIView):

    def __init__(self, *arg, **kwargs):
        super().__init__(*arg, **kwargs)
        self.names = ['a', 'b', 'c']

    def get_serializer(self, *args, **kwargs):
        serializer_class = CatSerializer
        return serializer_class(
            *args, **kwargs,
            names=self.names
        )

    def post(self, request):

        request_body = request.body
        serializer = self.get_serializer(
            data=json.loads(request_body),
        )
        is_data_valid = serializer.is_valid()
        if is_data_valid:
            serialized_data = serializer.data
            return Response({"message": "success", "serialized-data": serialized_data})
        else:
            return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

这是我问题的简化版。
我试图动态初始化一个序列化器,它有一个选择字段name,它的选择来自初始化后传递给序列化器的kwargs。
如果我在这个类上调用OPTIONS方法,它返回

{
    "name": "Cat",
    "description": "",
    "renders": [
        "application/json",
        "text/html"
    ],
    "parses": [
        "application/json",
        "application/x-www-form-urlencoded",
        "multipart/form-data"
    ],
    "actions": {
        "POST": {
            "name": {
                "type": "choice",
                "required": true,
                "read_only": false,
                "label": "Name",
                "choices": [
                    {
                        "value": "a",
                        "display_name": "a"
                    },
                    {
                        "value": "b",
                        "display_name": "b"
                    },
                    {
                        "value": "c",
                        "display_name": "c"
                    }
                ]
            }
        }
    }
}

如果我发出一个POST请求并传递一个

{
    "name": "d"
}

它正确地返回

{"name":["\"d\" is not a valid choice."]}

但如果我传递一个

{
    "name": "a"
}

我看到此错误

AttributeError: Got AttributeError when attempting to get a value for field `name` on serializer `CatSerializer`.
The serializer field might be named incorrectly and not match any attribute or key on the `CatSerializer` instance.
Original exception text was: 'CatSerializer' object has no attribute 'name'.

有什么想法吗?

bvjxkvbb

bvjxkvbb1#

尝试创建一个dynamic_serializer_method,如下所示:

def dynamic_serializer(choices):
    class CatSerializer(serializers.Serializer):
        name = serializers.ChoiceField(choices=choices)
    return CatSerializer

和视图集上:

def get_serializer(self, *args, **kwargs):
        serializer_class = dynamic_serializer(self.names)
        return serializer_class(*args, **kwargs)

相关问题