drf-writable-nested
drf-writable-nested copied to clipboard
Atomic transaction
Now, to avoid partial object creation you should wrap your root serializer's save()
into transaction.atomic
.
I'm not sure about wrapping save()
in the library in each serializer with mixin. What do you think?
@kenny1992 suggested to determine the root serializer depending on serializer.parent
We use a ModelViewSet
mixin to wrap create
, update
and destroy
in a transaction. We do this because we use signals for some critical (but intentionally decoupled) logic. If we don't wrap these calls, a failed signal handler won't roll back the actual database change.
The opposite is also possible. Someone may consider the data critical even if a signal were to fail. Forcing them to wrap the save
method in a transaction would not be backwards compatible as they would lose that data.
In general, I'm +1 on wrapping calls in transactions. It strikes me as the safe default. If someone has to improve their code (by handling errors in signal handlers) to upgrade drf-writable-nested
, that's not a bad thing. The few people who need to disable the feature (e.g. for performance reasons) should be skilled enough to undo the change.
I'd love to see this happen as it's not obvious to me how to implement the feature in the current state of the library.
Wouldn't adding something like this be enough?
class AtomicNestedCreateMixin(NestedCreateMixin):
def save(self, **kwargs):
with transaction.atomic():
return super().save(**kwargs)
Wouldn't adding something like this be enough?
class AtomicNestedCreateMixin(NestedCreateMixin): def save(self, **kwargs): with transaction.atomic(): return super().save(**kwargs)
厉害!