Является ли serializer.save() атомарным?

@api_view(["POST"])
def register_view(request: "Request"):
    serializer = RegisterSerializer(data=request.data)

    serializer.is_valid(raise_exception=True)

    try:
        serializer.save()
    except IntegrityError:
        raise ConflictException

    return Response(serializer.data, status=status.HTTP_201_CREATED)
class ConflictException(APIException):
    status_code = 409
    default_detail = "username is already taken"
    default_code = "conflict"
    def test_username_taken(self):
        with transaction.atomic():
            User.objects.create_user(username="customer4", password="Passw0rd!")

        response = self.client.post(
            "/register",
            {
                "username": "customer4",
                "password": "Passw0rd!",
                "confirm_password": "Passw0rd!",
                "phone_number": "13324252666"
            },
        )
        self.assertEqual(response.status_code, status.HTTP_409_CONFLICT)

Результат теста показывает :

raise TransactionManagementError( django.db.transaction.TransactionManagementError: В текущей транзакции произошла ошибка. Вы не можете выполнять запросы до конца 'атомарного' блока.

Я новичок в Django и DRF и не знаю, что делать...

Я протестировал на postman и проблемы нет, с ответом 409 status_code

Код состояния 409 используется для указания на конфликт с текущим состоянием ресурса, например, при попытке создать или обновить ресурс, который уже существует или имеет противоречивую информацию.

Я предполагаю, что он уже существует.

поэтому я рекомендую не использовать атомарные транзакции некоторое время

и serilizer.save не является атмоичным.

Вы можете настроить свой тест следующим образом.

class RegisterViewTests(APITestCase): def setUp(self): self.client = APIClient() User.objects.create_user(username="customer4", password="Passw0rd!")

def test_username_taken(self):
    response = self.client.post(
        "/register",
        {
            "username": "customer4",
            "password": "Passw0rd!",
            "confirm_password": "Passw0rd!",
            "phone_number": "13324252666"
        },
    )
    self.assertEqual(response.status_code, status.HTTP_409_CONFLICT)
Вернуться на верх