If you've ever built email/phone verification into a Django app, there's a good chance your OTP flow looks something like this: otp = random . randing ( 100000 , 999999 ) user . otp_code = otp user . save () It works in local testing. But it also quietly makes four mistakes that most Django OTP tutorials skip entirely, mistakes that only surface once real traffic, multiple servers, and actual attackers enter the picture. Mistake #1: Using ...