[Django]-Django testing client.login(): Your database backend doesn't behave properly when autocommit is off. Turn it on before using 'atomic'

3👍

I found a solution. I needed to add this at the beginning of the test method call and, thereby, wrap the whole test method call in this to turn autocommit on:

def testShouldRedirectToDashboardAfterSuccessfulLogin(self):
    from django.db import transaction
    transaction.set_autocommit(True)
    try:
        from django.contrib.auth.models import User
        u = User.objects.create_user(
            username="a@b.cz",
            password='aaaaa',
            email="a@b.cz"
        )

        self.assertTrue(self.client.login(
            username='a@b.cz',
            password='aaaaa'
        ))
    finally:
        u.delete()
        transaction.set_autocommit(False)

I hope this helps someone. I am still a bit confused why I had to do this because the documentation says that in Django 1.6, “Autocommit is initially turned on. If you turn it off, it’s your responsibility to restore it.” If you have any valuable info to add to this, feel welcome to comment below. I’ll make sure to upvote your comment if it sheds more light on this.

👤pkout

1👍

I ran into this with sqlite3 db, using Django 1.6. Here are the solutions.

  1. django.middleware.transaction.TransactionMiddleware has been deprecated. If you don’t have this in your settings.py file, you should not get the error.

  2. Accidentally, I found that including ATOMIC_REQUESTS: True works around the error if you had left django.middleware.transaction.TransactionMiddleware in your middlewares list.

E.g.

DATABASES = {
  'default': {
    'ENGINE': 'django.db.backends.sqlite3',
    'NAME': 'sqlite3-db',
    'ATOMIC_REQUESTS': True
  }
}

Leave a comment