You can't execute queries until the end of the 'atomic' block.


django.db.transaction.TransactionManagementError


いつ起きたの?


Unit Testでの整合性のテストエラー

class TestSignUpView(TestCase) :
    def setUp(self) :
        User.objects.create(
            id       = 1,
            username = 'test',
            password = '1234'  
        )

...

    def test_fail_sign_up_raise_integrity_error(self) :
        client = Client()
        
        user = {
            'id'       : 2,
            'username' : 'test',
            'password' : '1234'
        }
        
        response = client.post("/users/signup", json.dumps(user), content_type='application/json')
        
        self.assertEqual(response.status_code, 400)
        self.assertEqual(response.json(), {'message': 'IntegrityError'})

...

django.db.transaction.TransactionManagementError: 
An error occurred in the current transaction. 
You can't execute queries until the end of the 'atomic' block.

既存のコード

class SignUpView(View) :
    def post(self, request) :
        try :
            data = json.loads(request.body)
        
            username = data['username']            
            password = bcrypt.hashpw(data['password'].encode('utf-8'), bcrypt.gensalt()).decode('utf-8')
            
            User.objects.create(username = username, password = password)
            
            return JsonResponse({'message' : 'CREATE_USER'}, status=201)
        
        except KeyError :
            return JsonResponse({'message' : 'KeyError'}, status=400)

        except IntegrityError :
            return JsonResponse({'message' : 'IntegrityError'}, status=400)
これは会員登録に関するコードです.Userのパターンはusernamepasswordの2つのデータを受信して記憶する.
ただしusernameUnique=Trueに設定、
会員登録の場合、既存のものに加入したい場合は、integrity Errorが発生します.

解決策


検索では関連記事に従って修正されており、簡単な方法です.django.testではなくTestCaseを継承したTransactionTestCase.
テストさせてください.
そこで、次のように変更した最初のテストケース継承セクションを実行しました.
class TestSignUpView(TransactionTestCase) :

髪が大きい.