【问题标题】:problem initializing django serializer with extra vars to be used in choice fieldproblem initializing django serializer with extra vars to be used in choice field
【发布时间】:2022-12-27 22:55:09
【问题描述】:

I have a django serializer like this

# 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)

This is a simplified version of my question.

I am trying to dynamically initialize a serializer that has a choice field name and its choices are coming from kwargs passed to the serializer once initialized.

if I call OPTIONS method on this class it returns

{
    "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"
                    }
                ]
            }
        }
    }
}

and if I make a POST request and pass a payload of

{
    "name": "d"
}

it correctly returns

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

but if I pass a payload of

{
    "name": "a"
}

I see this error

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'.

Any thoughts thoughts is the problem?

【问题讨论】:

  • There may be small things to correct in the code you presented, but I think the error don't match this code, can you please check, because the error is very clear. you are trying to call the name value of your serializer (instance_of_ CatSerializer.name) but this call is not seen anywhere in the code present in the question.
  • this should be somewhere called in the internals of the serializer. maybe once we are calling .data in the views

标签: python django django-rest-framework django-serializer superclass


【解决方案1】:

try to create a dynamic_serializer_method Like this:

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

and on your Viewset:

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

【讨论】:

    猜你喜欢
    • 2022-06-15
    • 2017-10-26
    • 1970-01-01
    • 2022-10-25
    • 2022-11-30
    • 2013-10-30
    • 2022-12-26
    • 2022-12-02
    • 2018-07-28
    相关资源
    最近更新 更多