Search code examples
django-rest-frameworkdjango-serializer

DjangoREST: Extracting value from POST request to use in overridden create method


I am trying to accomplish a simple task of extracting the value passed from the POST request and using it as a parameter inside the overridden create method.

This is the example POST request body JSON, and "documented" is the field I wish to extract.

### POST
{
  "url": "aaaa",
  "title": "bbbb",
  "publisher": "bbbb",
  "desc": "bbbb",
  "summary": "bbbb",
  "documentId": "onDKe6K"
}

Using validated_data.pop("documentId") was the most obvious choice. However, I need DocumentListingField set to read_only=False in order to use this method. And that option raised larger issues as my Document model has an Hashfield that is not easily serializable.

Is there any other way to accomplish what I want in this situation? I've tried all of these but they all failed with "KeyError: documented"

  • validated_data.get("documentId")
  • validated_data["documentId"]

serializers.py

from django.forms.models import model_to_dict


class DocumentListingField(serializers.RelatedField):
    def to_representation(self, instance):
        return model_to_dict(instance.document)

class MySourceSerializer(serializers.ModelSerializer):
    Document = DocumentListingField(many=False, read_only=True)

    class Meta:
        model = MySource
        fields = (
            "id",
            "url",
            "title",
            "publisher",
            "desc",
            "summary",
            "Document",
        )

    def create(self, validated_data):
        documentId = validated_data.get("documentId").  <========= LINE OF INTEREST
        print(documentId)
        source = MySource.objects.create(
            document=Document.objects.get(id=documentId), **validated_data
        )
        print(validated_data)
        source.save()
        return source

Solution

  • I think you can set the documentId field in the serializer.

    class MySourceSerializer(serializers.ModelSerializer):
        Document = DocumentListingField(many=False, read_only=True)
        documentId = serializers.CharField(write_only = True)
    
        lass Meta:
        model = MySource
        fields = (
            ...
            "documentId",
        )