Home > Mobile >  How to POST an entity specifiying an integer foreign key in django rest framework
How to POST an entity specifiying an integer foreign key in django rest framework

Time:11-20

I am building a chat application with django rest framework and I m currently working on messages. This are my models:

from django.db import models
from django.contrib.auth.models import User

class Message(models.Model):
    text = models.CharField(max_length=500)
    datetime = models.DateTimeField(auto_now_add=True)
    user = models.ForeignKey(User, on_delete=models.CASCADE);

I am using the Django auth User model. This is my ModelViewSet for the messages:

class MessageViewSet(ModelViewSet):
    queryset = Message.objects.all()
    serializer_class = MessageSerializer

And these are my serializers:

class UserSerializer(serializers.ModelSerializer):
    class Meta:
        model = User
        fields = ['username']

class MessageSerializer(serializers.ModelSerializer):
    user =  UserSerializer(read_only=True)

    class Meta:
        model = Message
        fields = '__all__'

And this is my API:

enter image description here

The code I've written so far works really well for the GET functionally I want. I want for each message to get the username of the user it belongs to. But now I want the following thing: when I POST a new message, I want to be able to specify which user it belongs to by specifying the user's id. Right now I have only the "text" field in the POST section. I need to add a "user" field which takes in an integer (the user primary key) to specify which user the message belongs to. How should I refactor my code in order to do that?

CodePudding user response:

Because you've overridden the user field and set it to read_only=True, you cannot set a user when you're creating/updating a model.

If you just need the user's username, I'd suggest you to add a username field into MessageSerializer directly instead:

class MessageSerializer(serializers.ModelSerializer):
    username = serializers.CharField(source='user.username', read_only=True)

    class Meta:
        model = Message
        fields = '__all__'

Now you'll get this payload instead:

{
  "id": 1,
  "user": 1,
  "username": "timi",
  ...

And you should be able to set a user id now.

  • Related