我有一个用原子事务修饰的视图。但是,我总是想在这个视图中保存一个特定的操作。操作是调用第三方API,有时我需要在应用程序发出请求之前刷新令牌。但是,如果刷新后出现故障,则不会保存新令牌,而是回滚。如何始终将保存操作提交到数据库?我已经研究过使用asavepoint但我不确定我是否在正确的轨道上。views.py
@transaction.atomic
def my_view(request)
from another_file import fx
a = Mymodel.objects.first()
fx(a)
return a
another_file.py
def fx(obj)
from django.db import transaction
sid = transaction.savepoint()
obj.token = 'jfkds'
obj.save()
transaction.savepoint_commit(sid)
raise Exception
最佳答案
在“进程B”验证从“进程a”传递的身份验证所需的用户令牌(在进程a中的事务提交之前)出现类似问题:
为了解决这个问题,我需要“Token.objects.get_或_create(user=user)”调用来提交自己的事务,不管是否已经有一些周围的事务在进行中。我想你的问题也在考虑同样的问题。
我使用单独的数据库连接来处理令牌。因此在设置中:
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.postgresql_psycopg2',
'NAME': 'mydb',
'USER': 'mydbuser',
'PASSWORD': DBPASSWORD}}
DATABASES['security'] = DATABASES['default'] # allow independent security transactions/connections
DATABASE_ROUTERS = ['security.db_router.SecurityRouter']
路由器确保令牌模型在“安全”数据库中处理。您可以将路由器放置在您喜欢的位置,并使用上面的路由器设置将其链接
from rest_framework.authtoken.models import Token
class SecurityRouter(object):
def db_for_read(self, model, **hints):
return self.mine(model, **hints)
def db_for_write(self, model, **hints):
return self.mine(model, **hints)
def allow_relation(self, obj1, obj2, **hints):
return True
def allow_migrate(self, db, app_label, model=None, **hints):
return True
@staticmethod
def mine(model, **hints):
if model == Token:
return 'security'
所有令牌对象的使用现在都在“security”数据库中进行。因此,用户令牌是在独立于“默认”数据库事务的事务中创建的,它与所有django连接一样是即时的(除非您另外指定)。
关于python - 在Django原子事务中提交特定的保存操作,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/31253727/