[Answer]-How to deserialize foreignkey with django rest framework?

1👍

class ForeignKeyField(WritableField):

    def __init__(self, model_name, *args, **kwargs):
        super(ForeignKeyField, self).__init__(*args, **kwargs)
        self.model_name = model_name
        self.model_instance = None

    def from_native(self, pk):
        if not isinstance(pk, int):
            raise ValidationError("pk must be int")
        try:
            self.model_instance = self.model_name.objects.get(pk=pk)
            return self.model_instance
        except self.model_name.DoesNotExist:
            raise ValidationError('object does not exist')

    def to_native(self, obj):
        return self.model_instance

I hacked it, but I don’t konw why it works.

Usage:
there is a little difference

class t_serializer(serializers.Serializer):
    author = ForeignKeyField(Author)

@api_view(["POST"])
def func(request):
    serializer = t_serializer(data=request.DATA)
    if serializer.is_valid():
        print isinstance(serializer.data["author"], Author)
        #print True
    else:
        print serializer.errors

0👍

It appears that what you want is custom validation code.

For this particular instance, you could write the following.

class CreateBlogSerializer(serializers.Serializer):
    author = serializers.ForeignKeyField(Author)
    content = serializers.TextField()

    def validate_author(self, attrs, source):
        """
        Verify that the author exists.
        """
        author = attrs[source]
        if Author.objects.filter(pk=author).exists():
            return attrs
        raise serializers.ValidationError("Specified Author does not exist!")

Now when you call serializer.is_valid() this check will occur.

So you can then do this elsewhere in your code,

if serializer.is_valid():
     blog = Blog.objects.create(author=serializer.data["author"], content=serializer.data["content"])

And be sure that if the given blog is created, there is a corresponding Author already in the DB.

Detailed Explanation

So Django Rest Framework provides a method of adding custom validation to serializers. This can be done with by providing methods of the following format in the serializer class validate_<field name>. These methods will set the source value to name of the given field, in our example author, which can then be used with the attrs variable to get the current value of the field (attrs contains all the values passed into the serializer).

These validation methods are each called with then serializer.is_valid() method is called. They are supposed to just return attrs if the given test passes, and raise a ValidationError otherwise.

They can get somewhat complex, so it is probably best if you read the full documentation here, http://www.django-rest-framework.org/api-guide/serializers#validation

Leave a comment