Django-Rest сериализатор: Queryset не фильтрует результаты PrimaryKeyRelatedField

так у меня есть сериализатор, который выглядит так

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",
    ])
])

но если я изменю queryset в сериализаторе на

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",
    ])
])

это должно было произойти? Я неправильно использую querysets? Я использовал [] в качестве простого примера, чтобы показать, что неважно, что я ничего не меняется.

пожалуйста, любое понимание было бы бесценно

следует отметить, что masterlistings имеет первичное ключевое отношение, которое указывает на здания. Поэтому masterlisting принадлежат здания.

2 ответов


как указал @zymud, аргумент queryset в PrimaryKeyRelatedField используется для проверки ввода поля для создания новых записей. Другим решением для фильтрации masterlistings_set является использование сериализаторов.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)

queryset в соответствующем поле ограничивает только допустимые значения. Так и с queryset=[] вы не сможете добавить новые значения к masterlisting_set или создать новый Buildings.

обновление. Как использовать queryset для фильтрации

это немного BI сложно - вам нужно переписать ManyRelatedField и many_init метод RelatedField.

# 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)