'Django foreign key field read and write

I am using Django rest framework for a project. In the project, there is a Student model, which has a foreign key referring to a user object.

class Student(models.Model):
    user = models.OneToOneField(
        User,
        on_delete=models.CASCADE
    )

When I read from Student, I would also like to get all the fields of the nested user. I can do that with nested serializers:

class StudentSerializer(serializers.ModelSerializer):
    user = UserSerializer(read_only=True)
    
    class Meta:
        model = Student
        fields = '__all__'

However, if I want to create a new user I cannot use the same serializer, because there is no way to pass a foreign key to the user field, and Django does no support nested create.

I am currently using an additional field user_id = serializers.IntegerField(write_only=True) to get the foreign key for write, and customized the create method to handle the logic. I also tried using two different serializers for creating and fetching data. Both way worked, but I am just wondering if there is a more intuitive way to implement this? A more convenient or standard way perhaps? Is there some syntax that works like: if read: user = UserSerializer() that avoids creating two different things for the same serializer field under different conditions?



Solution 1:[1]

i think u should follow docs https://www.django-rest-framework.org/api-guide/relations/#writable-nested-serializers

class StudentSerializer(serializers.ModelSerializer):
    user = UserSerializer()
    
    class Meta:
        model = Student
        fields = '__all__'

    def create(self, validated_data):
        user_data = validated_data.pop('user')
        validated_data["user"] = User.objects.create(user_data)
        student = Student.objects.create(**validated_data)
        return student

You can also think about doing it in one transaction. https://docs.djangoproject.com/en/4.0/topics/db/transactions/

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 kjaw