PrimaryKeyRelatedField

PrimaryKeyRelatedField

我试图基于序列化程序上的其他布尔字段更改serializers.PrimaryKeyRelatedField的筛选器查找键,但未能成功。默认情况下,PrimaryKeyRelatedField按pk键筛选。在某些情况下(如果序列化器上的condition字段作为True发送),我只想用相关模型字段上的另一个字段(如remote_id)更改该筛选键。

class SomeSerializer(serializers.Serializer):
    condition = serializers.BooleanField(default=False)
    model_pks = serializer.PrimaryKeyRelatedField(queryset=Model.objects.all(), many=True)


到目前为止,我试图创建继承自PrimaryKeyRelatedField和overrideget_queryset方法的新字段(不确定是否要重写正确的方法),但无法访问conditionmodel_pks字段值。
class CustomPrimaryKeyRelatedField(PrimaryKeyRelatedField):
    def get_queryset(self):
        queryset = self.queryset
        # model_pks = sent model_pks
        if condition:
            return queryset.filter(remote_id__in=model_pks)
        return queryset.filter(id__in=model_pks)


另外,我尝试使用SerializerMethodField而不是像PrimaryKeyRelatedField那样;
class SomeSerializer(serializers.Serializer):
    condition = serializers.BooleanField(default=False)
    model_pks = serializer.SerializerMethodField()

    def get_model_pks(self, value):
        pks = self.initial_data.get('model_pks', [])
        if value.get('condition', False):
            return Model.objects.filter(remote_id__in=pks)
        return Model.objects.filter(pk__in=pks)


它提供了基于condition的更改查找键,但这次我不能用model_pks访问serializer.validated_data值。
是否有任何方法可以使用PrimaryKeyRelatedField进行条件查找键筛选?

最佳答案

我终于成功地创建了自定义主键字段。在这个自定义字段上,我重新创建了to_internal_value方法,并使用condition访问了self.root值。

class CustomPrimaryKeyRelatedField(PrimaryKeyRelatedField):
    def to_internal_value(self, data):
        condition = self.root.initial_data.get('condition', False)

        if self.pk_field is not None:
            data = self.pk_field.to_internal_value(data)
        try:
            if condition:
                return self.get_queryset().get(remote_id=data)
            else:
                return self.get_queryset().get(pk=data)
        except ObjectDoesNotExist:
            self.fail('does_not_exist', pk_value=data)
        except (TypeError, ValueError):
            self.fail('incorrect_type', data_type=type(data).__name__)

我不确定这是否是处理此类问题的最佳方式。但它现在解决了我的问题。

10-04 15:40