[Solved]-Django REST Framework – POSTing foreign key field containing natural key?

13👍

What you’re looking for is SlugRelatedField. See docs here.

but processing the srcPhone attribute as if it was a URL.

Exactly. You’re using HyperlinkedModelSerializer, so the srcPhone key is using a hyperlink relation by default.

The 'int' object has no attribute 'startswith' exception you’re seeing is because it’s expecting a URL string, but receiving an integer. Really that ought to result in a descriptive validation error, so I’ve created a ticket for that.

If you instead use a serializer something like this:

class CallSerializer(serializers.HyperlinkedModelSerializer):
    srcPhone = serializers.SlugRelatedField(slug_field='number')

    class Meta:
        model = Call
        fields = ('url', 'created', 'srcPhone')

Then the 'srcPhone' key will instead represent the relationship using the 'number' field on the target of the relationship.

I’m planning on putting in some more work to the relationship documentation at some point soon, so hopefully this will be more obvious in the future.

1👍

(Can’t post this as a comment, too long)

Tom’s answer above solved the problem.

However, I also want to have a hyperlinked field back to the Phone resource. The SlugRelatedField allows me to submit with an integer field belonging to the Phone, but when GETting the resulting Call resource, it also serialises as an integer. I’m sure this is intended functionality (doesn’t seem very elegant to have it serialising from an integer, but to a hyperlink). The solution I found was to add another field to the CallSerializer: src = serializers.HyperlinkedRelatedField(view_name='phone-detail',source='srcPhone',blank=True,read_only=True) and add that field to the Meta class. Then I POST only srcPhone (an integer) and GET srcPhone plus src, which is a hyperlink to the Phone resource.

👤EwanC

Leave a comment