ListSerializer с дочерним полем PrimaryRelatedKeyField

При использовании метода is_valid ListSerializer выполняется кверисет PrimaryRelatedKeyField Serializer, указанного в качестве дочернего, для количества элементов в Списке. Кверисет оценивается столько раз, сколько элементов в списке. Есть ли способ избежать этого? Я хочу, чтобы количество SQL-исполнений было как можно меньше.

class BookSerializer(serializers.ModelSerializer):
    title = serializers.CharField()
    publisher = serializers.PrimaryKeyRelatedField(queryset=Publisher.objects.all(), source="publisher")


class BookListSerializer(serializers.ListSerializer):
    child = BookSerializer()

    def create(self, validated_data):
        return Book.objects.bulk_create([Book(**book) for book in validated_data])



books = [
    {'title': 'Django Basic', 'publisher': 1},
    {'title': 'Django Advance', 'publisher': 2},
    {'title': 'DRF Basic', 'publisher': 1},
    {'title': 'DRF Advance', 'publisher': 2},
    {'title': 'Django Professional', 'publisher': 2},
]
bookListSerializer = BookListSerializer(data=books)
# In validation, queryset ( Publisher.objects.all() ) is evaluated every times.
# In this example, it will be executed five times.
bookListSerializer.is_valid(raise_exception=True)
bookListSerializer.save()

Если мы определим его как IntegerField в Serializer, указанном в качестве дочернего, он не будет выполнять много наборов запросов, но нам придется проверять в другой части, правильно ли указан id или нет.

class BookSerializer(serializers.ModelSerializer):
    title = serializers.CharField()
    publisher = serializers.IntegerField()


class BookListSerializer(serializers.ListSerializer):
    child = BookSerializer()

    def create(self, validated_data):
        return Book.objects.bulk_create([Book(**book) for book in validated_data])



books = [
    {'title': 'Django Basic', 'publisher': 1},
    {'title': 'Django Advance', 'publisher': 2},
    {'title': 'DRF Basic', 'publisher': 1},
    {'title': 'DRF Advance', 'publisher': 2},
    {'title': 'Django Professional', 'publisher': 2},
]

# Need a validation
book_id_list = [book['publisher'] for book in books]
if len(book_id_list) != Book.filter(id__in=book_id_list).count():
    raise serializers.ValidationError()

bookListSerializer = BookListSerializer(data=books)
bookListSerializer.is_valid(raise_exception=True)
bookListSerializer.save()
Вернуться на верх