Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/django/19.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python DRF操作中的原子事务?_Python_Django_Django Rest Framework - Fatal编程技术网

Python DRF操作中的原子事务?

Python DRF操作中的原子事务?,python,django,django-rest-framework,Python,Django,Django Rest Framework,我第一次尝试进入Django原子事务。我想知道是否有可能这样使用它: 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

我第一次尝试进入
Django原子事务
。我想知道是否有可能这样使用它:

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一起使用

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')

如果需要将所有API调用和DRF操作包装到事务中,则可以根据您的情况选择保存点

——您可以使用()Django数据库设置[来自Django 1.8]

DATABASES = {
    "default": {
        ....
        "ATOMIC_REQUESTS": True,
如果使用自定义异常处理程序(),则可能需要如下所示进行调整

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

答案是肯定的。哪一个装饰器先做有什么区别吗?我没有测试它,但我确信@transaction.atomic最终会起作用。好的,还有一个问题-
sid=transaction.savepoint()
-我应该在每个方法的开头都做一个保存点,或者如果我希望一些更新通过,一些更新失败后回滚,我可以选择吗?