【问题标题】:Filter serializer field's queryset based on current instance根据当前实例过滤序列化器字段的查询集
【发布时间】:2017-07-30 14:07:06
【问题描述】:

在像下面这样的 HyperlinkedModelSerializer 中,如何根据模型的“当前”实例过滤 other_model_objects 字段的相关实例集? (也许通过某种方式使用 queryset 参数?)

class MyModelSerializer(serializers.HyperlinkedModelSerializer):
    other_model_objects = serializers.HyperlinkedRelatedField(
        many=True,
        queryset=OtherModel.objects.filter(foo=current_instance.field),
        view_name='othermodel-detail'
    )

    class Meta:
        model = MyModel
        fields = ('other_model_objects',)

【问题讨论】:

    标签: django serialization django-rest-framework django-queryset


    【解决方案1】:

    您是否尝试过继承HyperlinkedModelSerializer 并覆盖get_queryset,如文档中所述:CustomRelationalFields

    类似:

    class MyFilteredHyperlinkedRelatedField(serializers.HyperlinkedRelatedField):
        def get_queryset(self):
            queryset = super().get_queryset()
            # ... filter queryset
            return queryset
    
    class MyModelSerializer(serializers.HyperlinkedModelSerializer):
        other_model_objects = MyHyperlinkedRelatedField(
            many=True,
            queryset=OtherModel.objects.all(),
            view_name='othermodel-detail'
        )
    
        class Meta:
            model = MyModel
            fields = ('other_model_objects',)
    

    我认为您可以使用self.parent 访问get_queryset 中的MyModelSerializer 实例,但是我不确定它是否已记录/稳定。

    编辑

    queryset 参数(和get_queryset 方法)仅用于创建或更新期间的验证。这不是关于检索字段的值,而是关于该字段的允许值。

    如果您想根据实例过滤值,我可以建议使用返回您想要的过滤值的方法更新您的模型:

    class MyModel:
        ...
        def filtered_other_model(self):
            return self.other_model_relation_name.filter(....)
    

    然后使用source参数:

    class MyModelSerializer(serializers.HyperlinkedModelSerializer):
        other_model_objects = serializers.HyperlinkedRelatedField(
            many=True,
            queryset=OtherModel.objects.all(),
            view_name='othermodel-detail',
            source = 'filtered_other_model'
        )
    
        class Meta:
            model = MyModel
            fields = ('other_model_objects',)
    

    【讨论】:

    • 使用self.parent 我得到rest_framework.relations.ManyRelatedField 的实例,但self.parent.instance 抛出AttributeError
    • 使用self.root 我得到了具有instance 属性的序列化程序。但是,它仅适用于详细视图,不适用于 instanceNone 的列表视图
    • 确实我忘了many=True,self.parent.parent 给你什么?如果我没记错的话,在许多关系中,中间都有一个 ListSerializer。
    • Hmm.. get_queryset 实际上并没有在列表视图中被调用。 (我之前看到的是DRF在api视图上发送的create调用,切换到JSON视图可以看到没有调用)
    • 确实,它仅用于验证:The queryset used for model instance lookups when validating the field input. 您应该改写您的问题,以说明您要达到的目标。
    猜你喜欢
    • 1970-01-01
    • 2017-08-16
    • 1970-01-01
    • 1970-01-01
    • 2020-12-19
    • 2016-07-20
    • 2015-09-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多