Micromegas
Micromegas

Reputation: 1689

SerializerMethodField always returns the same value and excludes fields

I have an API that sends some sample data. I am trying to change the representation of the output, using Django's SerializerMethodField(). But it doesn't work as expected since I am always getting back the same data and the fields are not shown in my output.

I have three models that look like this: 2 Models which are related through foreign keys:

class Machine(models.Model):
    machine_name            = models.CharField(max_length=120)

    def __str__(self):
        return self.machine_name
class Project(models.Model):
    project_name            = models.CharField(max_length=120)

    def __str__(self):
        return self.project_name

And one model like this:

class Simulation(models.Model):
    user                    = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, default=1)
    machine                 = models.ForeignKey(Machine, on_delete=models.CASCADE, default=1)
    project                 = models.ForeignKey(Project, on_delete=models.CASCADE, default=1)

I create data like this:

test_api_local(method="post", data={"machine":2, "project":1 })

What I'd like to achieve is that when I send data with machine:2, it should write the name of this machine2 into the result. Like 'machine' : 'machinenametwo'.

I tried this using SerializerMethodField. I know it is ReadOnly, but since I do not actually change the data only manipulate it I thought something like this might work:

class SimulationSerializer(serializers.ModelSerializer):
    machine = serializers.SerializerMethodField()
    project = serializers.SerializerMethodField()


    class Meta:
        model = Simulation

        fields = ('project',
                  'machine',     
                  )

    def get_machine(self, obj):
        print(obj.machine)
        project_name = obj.project.project_name
        return str(project_name)

This does not work, since my field machine doesn't appear anymore. Also when debuggin it (with that print statement), I realize that no matter what data I send, it always prints out the name of my first machine.

If I do test_api_local(method="post", data={"machine":2, "project":1 }) it prints the name of machine 1.

If I do test_api_local(method="post", data={"machine":3, "project":1 }) it prints the name of machine 1. So same result....

So my question would be: Is what I try the correct way of doing it, and if so what am I doing wrong.

If it is not, what would be the way?

Thanks so much in advance for any help or hints!

Upvotes: 0

Views: 813

Answers (1)

A. J. Parr
A. J. Parr

Reputation: 8026

The reason you're getting a 1 for machine is because that is the default for the field. You're getting the default value because serializers.SerializerMethodField() is a read only serializer, so it won't accept the input. If you use PrimaryKeyRelatedField() then it will accept your data.

class SimulationSerializer(serializers.ModelSerializer):
    machine = serializers.PrimaryKeyRelatedField(queryset=Machine.objects.all())
    project = serializers.PrimaryKeyRelatedField(queryset=Project.objects.all())

    class Meta:
        model = Simulation
        fields = ('project', 'machine')

Upvotes: 1

Related Questions