1

I am using django rest framework to create an api endpoint. I am using the default user model django offers. I need to create a post which uses the user as a foreign key. A user called "author" in the post can have multiple posts.

This is an example of a post json.

[
    {
        "author": {
            "id": 1,
            "username": "sorin"
        },
        "title": "First Post",
        "description": "Hello World!",
        "created_at": "2020-08-05T14:20:51.981163Z",
        "updated_at": "2020-08-05T14:20:51.981163Z"
    }
]

This is the model.

class Post(models.Model):
    author = models.ForeignKey(User, on_delete=models.CASCADE)
    title = models.CharField(max_length=255)
    description = models.TextField()
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)

    def __str__(self):
        return self.title

This is the serializer.

class UserSerializer(serializers.ModelSerializer):

    class Meta:
        model = User
        fields = ('id', 'username')


class PostSerializer(serializers.HyperlinkedModelSerializer):

    author = UserSerializer()

    class Meta:
        model = Post
        fields = ('author', 'title', 'description', 'created_at', 'updated_at')

I am getting the error "The .create() method does not support writable nested fields by default." when trying to make a post request using a "username", "title" and "description".

Any help to how to solve this?

2

1 Answer 1

1

I like hooking in the create function of the serializer for these kind of use cases. Make sure your UserSerializer is set to read_only=True.

class PostSerializer(serializers.HyperlinkedModelSerializer):

    author = UserSerializer(read_only=True)

    class Meta:
        model = Post
        fields = ('author', 'title', 'description', 'created_at', 'updated_at')

    def create(self, validated_data):
       request = self.context['request']
       author_data = request.data.get('author')
       if author is None or not isinstance(author.get('id'), int):
           raise ValidationError({'author': ['This field is invalid.']})
       author_instance = get_object_or_404(User, id=author.get('id'))
       return Post.objects.create(author=author_instance, **validated_data)
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.