I really liked your project! Can you please help me implement the update of the User, so that when the email changes, a confirmation comes to the mail, and when the phone changes, sms confirmation comes. Thanks in advance!
My models:
class CustomUser(AbstractUser):
APPLICANT = "Applicant"
EMPLOYER = "Employer"
ROLE_CHOICES = (
(APPLICANT, "Applicant"),
(EMPLOYER, "Employer"),
)
username = models.CharField(max_length=255, unique=True, blank=True, null=True)
email = models.EmailField(("email address"), unique=False, max_length=254, blank=True,null=True)
role = models.CharField(max_length=50, choices=ROLE_CHOICES)
avatar = models.ImageField(("avatar"), upload_to="avatars/", null=True, blank=True)
is_staff = models.BooleanField(default=False)
is_active = models.BooleanField(default=True)
created_date = models.DateTimeField(auto_now_add=True)
updated_date = models.DateTimeField(auto_now=True)
blocked_until = models.DateTimeField(null=True, blank=True)
USERNAME_FIELD = "username"
REQUIRED_FIELDS = []
objects = UserManager()
def __str__(self):
return self.email
def get_phone(self):
try:
phone = self.phone.phone_number
except PhoneNumber.DoesNotExist:
phone = None
return phone
@property
def fullname(self):
return f"{self.first_name} {self.last_name}"
class PhoneNumber(models.Model):
user = models.OneToOneField(CustomUser, related_name='phone', on_delete=models.CASCADE)
phone_number = PhoneNumberField(unique=True)
security_code = models.CharField(max_length=120)
is_verified = models.BooleanField(default=False)
sent = models.DateTimeField(null=True)
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
class Meta:
ordering = ('-created_at', )
def __str__(self):
return self.phone_number.as_e164
def generate_security_code(self):
"""
Returns a unique random `security_code` for given `TOKEN_LENGTH` in the settings.
Default token length = 6
"""
token_length = getattr(base, "TOKEN_LENGTH", 6)
return get_random_string(token_length, allowed_chars="0123456789")
def is_security_code_expired(self):
expiration_date = self.sent + datetime.timedelta(
minutes=base.TOKEN_EXPIRE_MINUTES
)
return expiration_date <= timezone.now()
def send_confirmation(self):
twilio_account_sid = base.TWILIO_ACCOUNT_SID
twilio_auth_token = base.TWILIO_AUTH_TOKEN
twilio_phone_number = base.TWILIO_PHONE_NUMBER
self.security_code = self.generate_security_code()
# print(
# f'Sending security code {self.security_code} to phone {self.phone_number}')
if all(
[
twilio_account_sid,
twilio_auth_token,
twilio_phone_number
]
):
try:
twilio_client = Client(
twilio_account_sid, twilio_auth_token
)
twilio_client.messages.create(
body=f'Your activation code is {self.security_code}',
to=str(self.phone_number),
from_=twilio_phone_number,
)
self.sent = timezone.now()
self.save()
return True
except TwilioRestException as e:
print(e)
else:
print("Twilio credentials are not set")
def check_verification(self, security_code):
if (
not self.is_security_code_expired() and
security_code == self.security_code and
self.is_verified == False
):
self.is_verified = True
self.save()
else:
raise NotAcceptable(
_("Your security code is wrong, expired or this phone is verified before."))
return self.is_verified