3
votes

Being newbie to Django REST Framework, I have problems deserializing an object given its primary key in my ModelSerializer. For example, I have 2 serializers that extend ModelSerializer:

class CourierSerializer(serializers.ModelSerializer):
    class Meta:
        model = Courier
        fields = (
            "first_name",
            "last_name",
            "phone"
        )

class OrderSerializer(serializers.ModelSerializer):
    courier = CourierSerializer()

    class Meta:
        model = Order
        fields = (
            "number",
            "courier"
        )

And my class based view looks like this:

class OrderList(generics.ListCreateAPIView):
    model = Order
    serializer_class = OrderSerializer

Now, when I serialize my Order model to JSON I get exactly what I want - object "Order" with detailed nested information about it's "Courier":

[
    {
        id: 1,
        number: "000231",
        courier: {
            id: 2,
            first_name: "John",
            last_name: "Smith",
            phone: "12345678"
        }
    },
    ...
]

but on POST call from client-side I want to receive just a foreign key to Courier:

{
    id: 1,
    number: "000231",
    courier: 2
}

What should I add to my OrderSerializer class to deserialize that kind of JSON into Order model? Should I write restore_object()? Or should I write additional serializer to deserialize? How is it gonna work with my (generics.ListCreateAPIView) view, can I use two separate serializers (one for list, one for post) for this purpose?

1

1 Answers

4
votes

You can add additional serializer with primary key to Courier:

class OrderSerializerForPost(serializers.ModelSerializer):
    courier = serializers.PrimaryKeyRelatedField()

    class Meta:
        model = Order
        fields = (
            "number",
            "courier"
        )

And then use it with your overrided post mehtod...

class OrderList(generics.ListCreateAPIView):

    model = Order
    serializer_class = OrderSerializer

    def post(self, request):
        self.serializer_class = OrderSerializerForPost
        super(OrderList, self).post(request)

Or you can try redefine your get_serializer_class method:

class OrderList(generics.ListCreateAPIView):

    model = Order
    serializer_class = OrderSerializer

    def get_serializer_class(self):
        if self.request.method == 'GET':
            return self.serializer_class
        elif self.request.method == 'POST':
            return OrderSerializerForPost