encode / django-rest-framework

Web APIs for Django. 🎸
https://www.django-rest-framework.org
Other
28.2k stars 6.82k forks source link

Does not work the source parameter in serializers.Serializer. #7166

Closed ryo-ma closed 4 years ago

ryo-ma commented 4 years ago

Environment

Steps to reproduce

class MySerializer(serializers.Serializer):
    my_field_name = serializers.CharField(max_length=32, source='myFieldName') # does not recognize source

class MyAPIView(APIView):
    def get(self, request, pk):
        data = {'myFieldName': 'xxxxxxxx'}
        serializer = MySerializer(data=data)
        serializer.is_valid()
        return Response(serializer.data)
        # > serializer.data => {}

serializer.data is empty dict.

I got following errors when I executed a serializer.errors. {'myFieldName': [ErrorDetail(string='This field is required.', code='required')]}

I seemed that does not work source parameter in serializers.Serializer.


However, the source parameter is working when I used the many parameter. serializer.data is [OrderedDict([('my_field_name', 'xxxxxx')])]

class MySerializer(serializers.Serializer):
    my_field_name = serializers.CharField(max_length=32, source='myFieldName')

class MyAPIView(APIView):
    def get(self, request, pk):
        data = [{'myFieldName': 'xxxxxxxx'}] # Change to list data.
        serializer = MySerializer(data=data, many=True) # Insert a `many` parameter.
        serializer.is_valid()
        return Response(serializer.data)
        # > serializer.data => [OrderedDict([('my_field_name', 'xxxxxx')])]

Expected behavior

I would like to success validation using the source parameter. I will get OrderedDict([('my_field_name', 'xxxxxx')]) from the serializer.data

Actual behavior

serializer.data is empty dict.

I got following errors when I executed a serializer.errors. {'myFieldName': [ErrorDetail(string='This field is required.', code='required')]}

napsterv commented 4 years ago

DRF 3.11 minimum support is Django 1.11

ryo-ma commented 4 years ago

I made a mistake writing it. I'm using Django 2.2.9.

ryo-ma commented 4 years ago

I resolved. I used source and field name in reverse. However, I wonder why I can get my_field_name by the serializer.data when I specify the many parameter.

napsterv commented 4 years ago

Yeah, I performed a test, it worked fine.

As for the many=True maybe one of the experts may explain why.

Izcarmt95 commented 1 year ago

Hi , I think that you should re-open this issue, the expected behaivor is right!

I have same issue! but for me the solution works, but it should not be like that

auvipy commented 1 year ago

care to share test case?

Sigularusrex commented 3 months ago
from rest_framework import serializers

class CommentListResponseSerializer(serializers.Serializer):
    id = serializers.IntegerField()
    user_id = serializers.IntegerField(source="author_id")
    comment = serializers.CharField()
    identifier = serializers.CharField(max_length=1024)
    created_at = serializers.DateTimeField()
    is_edited = serializers.BooleanField()

# Sample data with the expected structure
    data = [
        {
            "id": 1,
            "author_id": 2,
            "identifier": "Test1",
            "comment": "This is a comment for Test1",
            "created_at": datetime(2021, 1, 1, 0, 0, tzinfo=UTC),
            "is_edited": False,
        },
        {
            "id": 2,
            "author_id": 2,
            "identifier": "Test2",
            "comment": "This is a comment for Test2",
            "created_at": datetime(2021, 1, 2, 0, 0, tzinfo=UTC),
            "is_edited": False,
        },
    ]

    # Test the serializer in isolation
    serializer = CommentListResponseSerializer(data=data, many=True)
    if serializer.is_valid():
        assert serializer.data == [
            {
                "id": 1,
                "user_id": 2,
                "comment": "This is a comment for Test1",
                "identifier": "Test1",
                "created_at": "2021-01-01T00:00:00Z",
                "is_edited": False,
            },
            {
                "id": 2,
                "user_id": 2,
                "comment": "This is a comment for Test2",
                "identifier": "Test2",
                "created_at": "2021-01-02T00:00:00Z",
                "is_edited": False,
            },
        ]
    else:
        raise Exception(serializer.errors)