SerializerMethodField始终返回相同的值,并排除字段

时间:2019-05-15 16:33:44

标签: django api django-rest-framework django-serializer

我有一个API,可以发送一些示例数据。我正在尝试使用Django的SerializerMethodField()更改输出的表示形式。但这并不能按预期工作,因为我总是返回相同的数据,并且字段未显示在输出中。

我有三个看起来像这样的模型:2个通过外键关联的模型:

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

还有一个这样的模型:

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)

我创建这样的数据:

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

我想要实现的是,当我使用machine:2发送数据时,它应该在结果中写入该machine2的名称。 像'machine' : 'machinenametwo'

我使用SerializerMethodField进行了尝试。我知道它是ReadOnly,但是由于我实际上并没有更改数据,只能操作它,所以我认为类似的事情可能会起作用:

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)

这不起作用,因为我的现场计算机不再出现。同样,在调试时(带有该打印语句),我意识到无论我发送什么数据,它总是会打印出我的第一台计算机的名称。

如果我执行test_api_local(method="post", data={"machine":2, "project":1 }),它将打印计算机1的名称。

如果我执行test_api_local(method="post", data={"machine":3, "project":1 }),它将打印计算机1的名称。同样的结果。...

所以我的问题是:我会尝试用正确的方式做事吗?如果是,我做错了什么事。

如果不是,那应该怎么办?

非常感谢您的帮助或提示!

1 个答案:

答案 0 :(得分:2)

获得1的原因是因为这是该字段的默认设置。由于serializers.SerializerMethodField()是只读的序列化程序,因此您将获得默认值,因此它将不接受输入。如果您使用PrimaryKeyRelatedField(),它将接受您的数据。

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')