'SerializerMethodField not showing all fields of serializer when no FK relationship exists

Desired result:

I have a nested API response as shown below:

{
    "subject": {
        "name": "math",
        "teacher": <uuid>,
        "teacher_name": "John"
    },
    "grade": 1,
}

teacher_name is a custom field which uses teacher.

It works when subject and grade are set. But when the FK subject is null, I get this response:

Unwanted result

{
    "subject": {
        "name": "",
        "teacher": null,
    },
    "grade": 1,
}

Question:

I would want teacher_name to also appear. I have tried setting it up as a serializers.CharField

teacher_name= serializers.CharField(
    source="teacher.name",
    read_only=True,
    allow_blank=True,
    default=None,
)

and a serializers.SerializerMethodField

teacher_name= serializers.SerializerMethodField()
def get_subject_teacher(self, obj):
    return obj.teacher.name

But to no success.

Here is my serializer for the nested API:

class StudentSerializer(serializers.ModelSerializer):
    subject = serializers.SerializerMethodField()
    def get_subject(self, obj):
        filtered_obj = getattr(obj, "subject", None)
        return SubjectSerializer(filtered_obj).data

    class Meta:
        model = Student
        fields = (
            "subject",
            "grade",
        )

class SubjectSerializer(serializers.ModelSerializer):
    teacher_name= serializers.CharField(
        source="teacher.name",
        read_only=True,
        allow_blank=True,
        default=None,
    )
    class Meta:
        model = Subject
        fields = (
            "name",
            "teacher",
            "teacher_name",
        )


Solution 1:[1]

Try this:

class SubjectSerializer(serializers.ModelSerializer):
    teacher_name= serializers.CharField(
        source="teacher.name",
        allow_blank=True,
        default=None,
    )
    class Meta:
        model = Subject
        fields = (
            "name",
            "teacher",
            "teacher_name",
        )

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