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)