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}")) raise BadRequest(_(f"Invalid attribute format: {attribute_pair}"))
for attr, value in kwargs.items(): for attr, value in kwargs.items():
if attr == "password" or attr == "confirm_password":
continue
if attr not in [ if attr not in [
"password", "groups",
"confirm_password", "user_permissions",
] and ( "is_verified",
attr "is_staff",
not in [ "is_active",
"groups", "is_superuser",
"user_permissions", ] or info.context.user.has_perm("vibes_auth.change_user"):
"phone_number",
"is_verified",
"is_staff",
"is_active",
"is_superuser",
]
or info.context.user.has_perm("vibes_auth.change_user")
):
setattr(user, attr, value) setattr(user, attr, value)
user.save() user.save()
return UpdateUser(user=user) 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.db.models.signals import post_save, pre_save
from django.dispatch import receiver from django.dispatch import receiver
@ -7,17 +8,24 @@ from vibes_auth.utils.emailing import send_verification_email_task
@receiver(post_save, sender=User) @receiver(post_save, sender=User)
def send_verification_email_signal(instance, created, **kwargs): def send_verification_email_signal(instance, created, **kwargs):
if created: if not created:
send_verification_email_task.delay(instance.pk) return
send_verification_email_task.delay(instance.pk)
@receiver(pre_save, sender=User) @receiver(pre_save, sender=User)
def send_user_verification_email(instance, **kwargs): def send_user_verification_email(instance, **kwargs):
if instance.pk: if not instance.pk:
try: return
old_instance = User.objects.get(pk=instance.pk)
if old_instance.email != instance.email: try:
instance.is_active = False old = User.objects.get(pk=instance.pk)
send_verification_email_task.delay(instance.pk) except User.DoesNotExist:
except User.DoesNotExist: return
pass
if old.email != instance.email:
instance.is_active = False
transaction.on_commit(
lambda: send_verification_email_task.delay(instance.pk)
)