序列化程序需要在 GET 中包含更多信息,同时在 POST 中接受原语

Serializer needs to include more info in a GET while accepting primitives in a POST

现在我有以下序列化程序:

class ShiftSerializer(serializers.ModelSerializer):
    confirmed_location = LocationSerializer(required=False)

    class Meta:
        model = Shift

当我创建一个新的 Shift 对象时,我可以像这样传递一个基本对象...

{date_requested: "2015-06-11", employee: 4, shift_requested: 2}

...对象的创建没有问题。

为了使 Shift 对象更详细地说明谁请求了它们,我为 Employee 字段声明了一个序列化程序,以便我的 GET 将包含有关员工的信息:

class ShiftSerializer(serializers.ModelSerializer):
    confirmed_location = LocationSerializer(required=False)
    employee = EmployeeSerializer(required=False)

    class Meta:
        model = Shift

这产生了预期的效果:现在我可以看到谁请求了轮班,而无需为每个用户向服务器进行第二次查询。不幸的是,这样做之后,每当我尝试 POST 同一个对象来创建新的 Shift:

时,我就开始收到 HTTP 400 错误

Invalid data. Expected a dictionary, but got int.

我敢肯定 EmployeeSerializer 很糟糕,因为我没有传递整个 Employee 对象,只有一个指向特定 Employeeid .是否可以在 GETing Shift 对象时包含整个 Employee 对象,但在 POSTing 创建新的 Shift 对象时仍然只接受一个整数?

要获得员工的只读表示,您可以添加 SerializerMethodField。这将使 employee 字段完整无缺地用于 POSTPUT 请求,并在 employee_data.

处添加序列化表示
class EmployeeSerializer(serializers.ModelSerializer):
    class Meta:
        model = Employee

class ShiftSerializer(serializers.ModelSerializer):
    confirmed_location = LocationSerializer(required=False)

    # this will look for a method named get_employee_data
    employee_data = serializers.SerializerMethodField()

    class Meta:
        model = Shift
        fields = (
            'confirmed_location', 
            'date_requested', 
            'shift_requested',
            'employee',
            'employee_data',
        )

    def get_employee_data(self, obj):
        """ Returns serialized representation of an employee.
        """
        return EmployeeSerializer(obj.employee).data