Сериализатор Django DRF с many=true пропускает соответствующую функцию validate()
Я столкнулся со следующей проблемой:
Имеется 2 сериализатора CreateSerializer(дочерний) и BulkCreateSerializer(родительский). Они связаны через list_serializer_class. Я переопределил методы create() и validate() для обоих сериализаторов и ожидаю, что они будут срабатывать соответственно на то, приходит ли один экземпляр через POST или список экземпляров.
Однако, когда я отправляю post запрос со списком экземпляров, сериализатор действительно переключается на many=true, но использует validate(), принадлежащий дочернему CreateSerializer, вместо выделенного BulkCreateSerializer, что, конечно же, приводит к ошибкам.
Так что мой вопрос заключается в том, что может быть логикой под капотом, которая не позволяет моим сериализаторам распределять элементы для валидации соответственно? И как заставить его работать таким образом?
serializers.py
views.py
class DraftsRecipeStepsCreateView(APIView):
    
    serializer_class = RecipeStepDraftCreateSerializer  
    def post(self, request, *args, **kwargs):
        print(f'DATA IS LIST: {isinstance(request.data, list)}')
        
        serializer = self.serializer_class(
            data=request.data, 
            many=isinstance(request.data, list), 
            context={
                'request': request,
                'recipe_id': kwargs.get('recipe_id')})
        serializer.is_valid(raise_exception=True)
        serializer.save()   
        return Response(serializer.data, status=status.HTTP_201_CREATED)
                
 Код, объясняющий такое поведение, можно найти here. Он описывает, как сериализатор списков выполняет валидацию (метод run_validation).
 Исходя из этого, сериализатор списка сначала проверяет каждый дочерний сериализатор, как показано в реализации to_internal_value:
    def to_internal_value(self, data):
        ...
        for item in data:
            try:
                validated = self.child.run_validation(item)
            except ValidationError as exc:
                errors.append(exc.detail)
            else:
                ret.append(validated)
                errors.append({})
        ...
перед выполнением собственного списка проверьте:
    def run_validation(self, data=empty):
        ...
        value = self.to_internal_value(data) # <-- children validation first
        try:
            self.run_validators(value) # <-- then the list validation
        ...
Я попробовал это с нижеприведенным сериализатором:
class MyModelListSerializer(serializers.ListSerializer):
    def validate(self, attrs):
        print('mymodel list validate')
        return attrs
class MyModelSerializer(serializers.ModelSerializer):
    class Meta:
        model = MyModel
        fields = '__all__'
        list_serializer_class = MyModelListSerializer
    def validate(self, attrs):
        print('mymodel validate')
        return attrs
используя некоторые выборочные данные, а затем проверяя:
somedata = [
    {
        "data": "1",
    },
    {
        "data": "2",
    }
]
s = MyModelSerializer(data=somedata, many=True); s.is_valid();
Вывод, который я получаю, соответствует тому, что предлагает источник:
mymodel validate
mymodel validate
mymodel list validate
 В вашем случае я подозреваю, что print("bulk validate") не сработал, потому что возникли проблемы с проверкой дочерних сериализаторов, в результате чего сериализатор списка больше не запускается.
