我正试图第一次进入Django atomic transactions
。我想知道是否有可能使用这样的东西:
class TaskViewSet(MultiSerializerViewSet):
@transaction.atomic
@action(methods=['PATCH'], detail=True)
def move_task(self, request, pk):
# making queries, trying to update them, roll back if last one fails.
return Response("message: SUCCESS", status=_status.HTTP_200_OK)
我进行了一些搜索-有关如何使用事务的一些信息,但是如果可以在DRF中使用它们,我没有找到任何信息。
答案 0 :(得分:1)
class PayViewSet(ModelViewSet):
@action(methods=['PATCH'], detail=True)
@transaction.atomic
def approval(self, request, *args, **kwargs):
sid = transaction.savepoint()
success = something
if success:
transaction.savepoint_commit(sid)
return success_response('yes')
else:
transaction.savepoint_rollback(sid)
return error_response('no')
保存点视情况而定
答案 1 :(得分:0)
如果您需要将所有API调用和DRF动作包装到事务中,则可以使用[ATOMIC_REQUEST)Django数据库设置(来自Django 1.8)< / p>
DATABASES = {
"default": {
....
"ATOMIC_REQUESTS": True,
如果您使用自定义异常处理程序(DRF Issue),则可能需要进行如下调整
REST_FRAMEWORK = {
....
"EXCEPTION_HANDLER": "api.exceptions.your_exception_handler",
}
import logging
from django.db import IntegrityError
from rest_framework.response import Response
from rest_framework.views import exception_handler, set_rollback
def your_exception_handler(exc, context):
"""
DRF custom exception handler. This will allow us to add useful information
to any exceptions to help out our frontend devs
"""
# Call REST framework's default exception handler first, to get the standard error response.
response = exception_handler(exc, context)
if not response and isinstance(exc, IntegrityError):
# https://github.com/encode/django-rest-framework/issues/5760
if 'duplicate key value violates unique constraint' in str(exc):
set_rollback()
msg = "Unique constraint violated: {exc}".format(exc=exc)
response = Response({"error": True, "content": msg}, status=400)
if response is None:
set_rollback()
logger.exception(exc)
response = Response({"error": True, "content": str(exc)}, status=500)
return response