【问题标题】:Django-REST Serializer: Queryset does not filter PrimaryKeyRelatedField resultsDjango-REST Serializer:查询集不过滤 PrimaryKeyRelatedField 结果
【发布时间】:2016-08-13 20:05:58
【问题描述】:

所以我有一个看起来像这样的序列化程序

class BuildingsSerializer(serializers.ModelSerializer):
    masterlisting_set = serializers.PrimaryKeyRelatedField(many=True, 
                                    queryset=Masterlistings.objects.all())

效果很好

serializer = BuildingsSerializer(Buildings.objects.get(pk=1))
serializer.data 

生产

OrderedDict([
    ("masterlistings_set", [
        "0a06e3d7-87b7-4526-a877-c10f54fa5bc9",
        "343643ac-681f-4597-b8f5-ff7e5be65eef",
        "449a3ad2-c76c-4cb8-bb86-1be72fafcf64",
    ])
])

但如果我将序列化程序中的查询集更改为

class BuildingsSerializer(serializers.ModelSerializer):
     masterlistings_set = serializers.PrimaryKeyRelatedField(many=True, queryset=[])

我仍然得到相同的确切结果。

 OrderedDict([
    ("masterlistings_set", [
        "0a06e3d7-87b7-4526-a877-c10f54fa5bc9",
        "343643ac-681f-4597-b8f5-ff7e5be65eef",
        "449a3ad2-c76c-4cb8-bb86-1be72fafcf64",
    ])
])

这应该发生吗?我是否错误地使用了查询集? 我用 [] 作为一个简单的例子来表明无论我输入什么都不会改变。

请任何见解都是无价的

应该注意,主列表具有指向建筑物的主键关系。因此,主列表属于建筑物。

【问题讨论】:

    标签: python django serialization django-rest-framework


    【解决方案1】:

    queryset 在相关字段中仅限制可接受的值。因此,使用queryset=[],您将无法向masterlisting_set 添加新值或创建新的Buildings

    更新。如何使用查询集进行过滤

    这有点棘手 - 您需要在 RelatedField 中重写 ManyRelatedFieldmany_init 方法。

    # re-define ManyRelatedField `to_representation` method to filter values
    # based on queryset
    class FilteredManyRelatedField(serializers.ManyRelatedField):
        def to_representation(self, iterable):
            iterable = self.child_relation.queryset.filter(
                pk__in=[value.pk for value in iterable])
            return super(FilteredManyRelatedField, self).to_representation(iterable)
    
    
    # use overridden FilteredManyRelatedField in `many_init`
    class FilteredPrimaryKeyRelatedField(serializers.PrimaryKeyRelatedField):
        @classmethod
        def many_init(cls, *args, **kwargs):
            kwargs['child_relation'] = cls(queryset=kwargs.pop('queryset'))
            return FilteredManyRelatedField(*args, **kwargs)
    

    【讨论】:

    • 我明白了,谢谢你的信息。你知道用它来过滤掉我从序列化器得到的信息吗?
    • 哇!感谢您的宝贵时间!
    【解决方案2】:

    正如@zymud 所指出的,PrimaryKeyRelatedField 中的 queryset 参数用于验证字段输入以创建新条目。 过滤掉masterlistings_set的另一种解决方案是使用serializers.SerializerMethodField(),如下:

    class BuildingsSerializer(serializers.ModelSerializer):
        masterlisting_set = serializers.SerializerMethodField()
    
        def get_masterlisting_set(self, obj):
            return MasterListing.objects.filter(building=obj).values_list('pk',flat=True)
    

    【讨论】:

    • 太棒了,我接受了这个答案,因为它是两者中的清洁剂!
    • 你是圣人?(12:04 AM)
    猜你喜欢
    • 2013-04-20
    • 2021-11-23
    • 2017-02-08
    • 1970-01-01
    • 2019-03-20
    • 2020-09-25
    • 2021-11-10
    • 2017-10-22
    • 2016-02-03
    相关资源
    最近更新 更多