Reputation: 1689
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
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