Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

id is not present in validate() and ListSerializer's update() Django Rest Framework

I'm learning and new to Django Rest Framework and I'm having an issue in serializer validations and ListSerializer update method.

I have an APIView class which handles the put request. I just wanted to have a custom validation and so I've overridden validate method in the serializer class.

From postman I'm sending a JSON data to this APIView Class.

Sample JASON data:

[
{
            "id": 1,
            "ip": "10.1.1.1",
            "host_name": "hostname 1"
},
{
            "id": 2,
            "ip": "10.1.1.2",
            "host_name": "hostname 2"
}
]

When I receive the data and do serializer.is_valid() it passes the flow to the overridden validate function. But in there when I check for the attrs argument, I get all the fields except the id. The key and value for id are not present. It shows None.

The same issue occurred to me when I was trying to override the update method in ListSerializer.

when I tried the below code in the ListSerializer's update method,

data_mapping = {item['id']: item for item in validated_data}

I got an error saying KeyError 'id'.

It seems it's not accepting id field and I'm not sure why! Please, someone explain this to me if I'm wrong anywhere.

Serializer class

from rest_framework import serializers
from .models import NoAccessDetails


class NoAccessDetailsListSerializer(serializers.ListSerializer):
    def update(self, instance, validated_data)

        data_mapping = {data.id: data for data in instance}

        #Here I'm getting KeyError ID
        validated_data_mapping = {item['id']: item for item in validated_data}

        return 


class NoAccessDetailsSerializer(serializers.ModelSerializer):

    class Meta:
        model = NoAccessDetails
        list_serializer_class = NoAccessDetailsListSerializer
        fields = ("id", "ip", "host_name")

    def validate(self, data):

        id_val = data.get('id')
        ip = data.get('ip')
        host_name = data.get('host_name')

        #here the id value is None
        print('id val {} '.format(id_val))
        return data

like image 536
Aashay Amballi Avatar asked Sep 26 '19 19:09

Aashay Amballi


1 Answers

If I am understanding correctly, the issue is that you do not see the id field inside of validated_data. If so, I believe this is intentional in the framework:

https://github.com/encode/django-rest-framework/issues/2320

Basically, the id field is read_only by default. Let me know if you have questions that are not answered by Tom's response to that issue.

EDIT: Also feel free to share the higher level use case (what you are planning on doing with the ID inside of validation), and maybe we can offer alternative approaches.

like image 163
MrName Avatar answered Sep 23 '22 16:09

MrName