Features: 1) Add transaction hook to ensure send_verification_email_task runs after database commit.

Fixes: 1) Add missing import for `transaction` in `signals.py`; 2) Fix incorrect handling of `pre_save` skip logic for non-existent users; 3) Correct conditional logic for email change handling to avoid unnecessary activation resets.

Extra: 1) Simplify mutation attribute validation in `mutations.py` by excluding specific fields earlier in the loop; 2) Improve code readability with minor refactors in both `signals.py` and `mutations.py`.
This commit is contained in:
Egor Pavlovich Gorbunov 2025-05-20 15:04:55 +03:00
parent 4f4d4c5c10
commit 5a7f3d4883
2 changed files with 28 additions and 26 deletions

View file

@ -135,25 +135,19 @@ class UpdateUser(BaseMutation):
raise BadRequest(_(f"Invalid attribute format: {attribute_pair}"))
for attr, value in kwargs.items():
if attr == "password" or attr == "confirm_password":
continue
if attr not in [
"password",
"confirm_password",
] and (
attr
not in [
"groups",
"user_permissions",
"phone_number",
"is_verified",
"is_staff",
"is_active",
"is_superuser",
]
or info.context.user.has_perm("vibes_auth.change_user")
):
"groups",
"user_permissions",
"is_verified",
"is_staff",
"is_active",
"is_superuser",
] or info.context.user.has_perm("vibes_auth.change_user"):
setattr(user, attr, value)
user.save()
user.save()
return UpdateUser(user=user)

View file

@ -1,3 +1,4 @@
from django.db import transaction
from django.db.models.signals import post_save, pre_save
from django.dispatch import receiver
@ -7,17 +8,24 @@ from vibes_auth.utils.emailing import send_verification_email_task
@receiver(post_save, sender=User)
def send_verification_email_signal(instance, created, **kwargs):
if created:
send_verification_email_task.delay(instance.pk)
if not created:
return
send_verification_email_task.delay(instance.pk)
@receiver(pre_save, sender=User)
def send_user_verification_email(instance, **kwargs):
if instance.pk:
try:
old_instance = User.objects.get(pk=instance.pk)
if old_instance.email != instance.email:
instance.is_active = False
send_verification_email_task.delay(instance.pk)
except User.DoesNotExist:
pass
if not instance.pk:
return
try:
old = User.objects.get(pk=instance.pk)
except User.DoesNotExist:
return
if old.email != instance.email:
instance.is_active = False
transaction.on_commit(
lambda: send_verification_email_task.delay(instance.pk)
)