gpt4 book ai didi

python - 如何根据 4xx 或 5xx HTTP 状态代码使 django 模型原子性回滚

转载 作者:太空宇宙 更新时间:2023-11-03 16:53:06 26 4
gpt4 key购买 nike

据我了解,django 原子性仅在抛出异常时才回滚事务。但是,我在脚本中捕获了几个异常,对于这些异常,我正在生成一个很好的 HTTP 响应,其中包含一些对用户有意义的响应内容 - 但我始终确保在这种情况下的 HTTP 响应以正确的 4xx 发送出去或 5xx HTTP 状态代码。当发生这样的 HTTP 响应时,我希望 django 回滚迄今为止可能执行的所有数据库查询。但是,django 原子性似乎并不基于发送的 HTTP 状态代码进行操作,它仅基于向用户抛出的异常进行操作。有什么建议我可以在 python 2.7 上的 django 1.8 中解决这个问题吗?

最佳答案

尝试创建一个自定义中间件来执行此操作。这是 based on the old TransactionMiddleware 的一个示例(未经测试):

from django.db import transaction

class StatusCodeTransactionMiddleware(object):
"""
Rolls back the current transaction for all responses with 4xx or 5xx status
codes.
"""

def process_request(self, request):
"""Enters transaction management"""
transaction.enter_transaction_management()

def process_response(self, request, response):
"""Commits and leaves transaction management."""
if response.status_code >= 400:
if transaction.is_dirty():
# This rollback might fail because of network failure for
# example. If rollback isn't possible it is impossible to
# clean the connection's state. So leave the connection in
# dirty state and let request_finished signal deal with
# cleaning the connection.
transaction.rollback()
transaction.leave_transaction_management()
else:
if not transaction.get_autocommit():
if transaction.is_dirty():
# Note: it is possible that the commit fails. If the
# reason is closed connection or some similar reason,
# then there is little hope to proceed nicely.
# However, in some cases ( deferred foreign key checks
# for example) it is still possible to rollback().
try:
transaction.commit()
except Exception:
# If the rollback fails, the transaction state will
# be messed up. It doesn't matter, the connection
# will be set to clean state after the request
# finishes. And, we can't clean the state here
# properly even if we wanted to, the connection is
# in transaction but we can't rollback...
transaction.rollback()
transaction.leave_transaction_management()
raise
transaction.leave_transaction_management()
return response

将其放入您的MIDDLEWARE_CLASSES中,如下所示:

MIDDLEWARE_CLASSES = (
"myapp.middleware.StatusCodeTransactionMiddleware",
# Other middleware...
)

关于python - 如何根据 4xx 或 5xx HTTP 状态代码使 django 模型原子性回滚,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35689183/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com