Атомарная транзакция с более чем одной моделью

У меня есть представление, которое сохраняет данные в двух разных моделях "Eliel_FuncionarioAlocacao" и "Eliel_FuncionarioAlocacaoCentro", однако если возникает ошибка при создании "Eliel_FuncionarioAlocacaoCentro", оно не дает откат, чтобы не создавать также "Eliel_FuncionarioAlocacao", что я делаю неправильно в этом представлении?

from .serializers import FuncionarioAlocacaoSerializer
from auditlog.context import set_actor
from client.app_eliel.models import Eliel_FuncionarioAlocacao, Eliel_FuncionarioAlocacaoCentro
from django.db import transaction
from microservices.serializers import ActorSerializer
from oauth2_provider.contrib.rest_framework import OAuth2Authentication, TokenHasReadWriteScope
from project_datafit.utils import log_error
from rest_framework import status
from rest_framework.decorators import api_view, authentication_classes, permission_classes
from rest_framework.exceptions import ValidationError
from rest_framework.response import Response
import json
import re

@api_view(['POST'])
@authentication_classes([OAuth2Authentication])
@permission_classes([TokenHasReadWriteScope])
def funcionarioAlocacao_create_api(request):

    actor_serializer = ActorSerializer(data=request.data)
    funcionarioAlocacao_serializer = FuncionarioAlocacaoSerializer(data=request.data)

    try:

        actor_serializer.is_valid(raise_exception=True)
        funcionarioAlocacao_serializer.is_valid(raise_exception=True)

        actor = actor_serializer.validated_data['actor']
        matricula = funcionarioAlocacao_serializer.validated_data['matricula']
        data_inicio = funcionarioAlocacao_serializer.validated_data['data_inicio']
        data_fim = funcionarioAlocacao_serializer.validated_data['data_fim']
        obs = funcionarioAlocacao_serializer.validated_data.get('obs') 
        centros_data = funcionarioAlocacao_serializer.validated_data.get('centros', [])

        with transaction.atomic(): 
            with set_actor(actor):
                try:
                    funcionarioAlocacao = Eliel_FuncionarioAlocacao(Matricula=matricula, DataInicio=data_inicio, DataFim=data_fim, Obs=obs)
                    funcionarioAlocacao.save()

                    for centro_data_str in centros_data:
                        centro_data = json.loads(centro_data_str)
                        centro = centro_data.get('centro')
                        porcentagem = centro_data.get('porcentagem')

                        Eliel_FuncionarioAlocacaoCentro.objects.create(
                            IdAlocacao=funcionarioAlocacao,
                            CodCentro=centro,
                            Peso=porcentagem
                        )
        
                    return Response({'success': 'Alocação feita com sucesso'}, status=status.HTTP_200_OK)
                except Exception as e:
                    log_error(request.path, str(e), actor)
                    return Response({'error': 'Erro ao alocar funcionário'}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
            
    except ValidationError as e:
        error_message = str(e.detail)
        error_message = re.search(r"ErrorDetail\(string='([^']*)'", error_message).group(1)
        return Response({'error': error_message}, status=status.HTTP_400_BAD_REQUEST)

Я хочу, чтобы атомарная транзакция откатывалась при возникновении ошибки, создавала оба элемента модели или не создавала ни одного при возникновении ошибки

Обратите внимание, что для отката транзакции необходимо где-то вызвать ошибку!

Поскольку вы перехватываете все исключения, это не работает так, как должно быть! Это может быть по-разному в зависимости от ваших требований, но может быть что-то вроде:

From rest_framework.serializers import ValidationError

А затем в блоке исключений сделайте что-то вроде:

raise ValidationError("some errors")

Тогда код состояния вашего API будет равен 400 (опять же, это может быть и другое исключение, но оно должно быть поднято, чтобы откатить транзакции), и все ваши транзакции будут откачены, я полагаю.

Это повышение также должно быть в with transaction.atomic(): блоке!

Вернуться на верх