DRF-如何使用条件更改serializer.PrimaryKeyRelatedField的过滤器查找键?

时间:2019-10-22 13:16:02

标签: python django django-rest-framework django-queryset django-serializer

我正在尝试基于序列化程序上的其他布尔字段来更改serializers.PrimaryKeyRelatedField的过滤器查找键,但无法成功。默认情况下,按pk键过滤PrimaryKeyRelatedField。在某些情况下(如果序列化程序上的condition字段以True的形式发送),我只想用相关模型字段中的另一个字段(例如remote_id)来更改该过滤键。

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

到目前为止,我尝试创建一个从PrimaryKeyRelatedField继承并覆盖get_queryset方法(不确定覆盖正确方法)的新字段,但是我无法访问condition和{{1 }}字段值。

model_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进行条件查找关键字过滤?

1 个答案:

答案 0 :(得分:0)

我终于通过创建自定义主键字段成功解决了自己的问题。在此自定义字段上,我刚刚重新创建了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__)

我不确定这是否是解决此类问题的最佳方法。但这暂时解决了我的问题。