Django仅在视图成功完成后保存

时间:2013-12-12 13:57:45

标签: django

我正在使用Django 1.5.4,看起来它有这个调试设置,导致save方法在视图成功完成之前不保存。这使得用户注册和登录后的功能无法实现。

我试图设置DEBUG=False,没有帮助。 它发生在每个模型上。 我正在使用MySQL,但我很确定这根本不相关。 我正在使用电子邮件验证后端,这里是:

from django.contrib.auth.models import User


class EmailBackend():
    def get_user(self, user_id):
        try:
            return User.objects.get(pk=user_id)
        except User.DoesNotExist:
            return None

    def authenticate(self, username=None, password=None):
        try:
            user = User.objects.get(email=username)
        except User.DoesNotExist:
            return None

        if user.check_password(password):
            return user

我用来保存的代码很常见:

user = User()
user.first_name = full_name[0]
user.last_name = ' '.join(full_name[1:])
user.email = data['email']
user.username = create_username(user.first_name, user.last_name)
user.set_password(data['password'])
user.save()

auth_form = AuthenticationForm(data=request.POST or None)
if auth_form.is_valid():
    login(request, auth_form.get_user())

我也查看了1.5.3版和专业版的Django文档,但没有找到任何内容。

现在,这里可能会发生什么?

3 个答案:

答案 0 :(得分:2)

from django.db import transaction
with transaction.commit_on_success():
    user.save()

更多关于Database transactions

答案 1 :(得分:1)

Django会立即保存,但启用TransactionMiddleware后,只有在请求结束时才会提交事务

https://docs.djangoproject.com/en/1.5/topics/db/transactions/#tying-transactions-to-http-requests

  

处理Web请求中的事务的推荐方法是通过Django的TransactionMiddleware将它们与请求和响应阶段联系起来。

     

它的工作方式如下:当请求启动时,Django启动一个事务。如果生成的响应没有问题,Django会提交任何待处理的事务。如果视图函数产生异常,Django将回滚所有待处理的事务。

     

要激活此功能,只需将TransactionMiddleware中间件添加到MIDDLEWARE_CLASSES设置

您可以commit manually或转动autocommit开启整个视图:

from django.db import transaction

@transaction.autocommit
def viewfunc(request):
    ....

您也可以从TransactionMiddleware删除MIDDLEWARE_CLASSES,但我不建议这样做。

答案 2 :(得分:1)

只关注TransactionMiddleware 来自Django文档:

  

在Django 1.6中,TransactionMiddleware 已弃用,取而代之的是ATOMIC_REQUESTS。虽然一般行为是相同的,但有两点不同。

     

使用以前的API,可以切换到自动提交或在视图内的任何位置显式提交。由于ATOMIC_REQUESTS依赖于强制原子性的atomic(),因此不再允许这样做。但是,在顶层,仍然可以避免在事务中包装整个视图。为此,请使用non_atomic_requests()而不是autocommit()来装饰视图。

     

事务中间件不仅适用于查看功能,还适用于之后的中间件模块。例如,如果您在事务中间件之后使用会话中间件,则会话创建是事务的一部分。 ATOMIC_REQUESTS仅适用于视图本身。