RlM
RlM

Reputation: 277

How to add email and name fields into SendMail upon user creation in Django

I made a signal that triggers SendMail when I create a user. Only superusers can create users from the Admin site, the users can't register themselves. This is important form me. So the signal works well and when I create a new user it sends the email.

My problem is that in the Django Admin when I create a user I am not able to add the email address and first and last name until I save the user. But when I save it sends the mail without the mentioned fields because that moment those are blank.

How can I do that the signal wait for the second saving or modifying when I fill the email and name fields?

models.py

class Profile(models.Model):

    def __str__(self):
        return str(self.user)

    user = models.OneToOneField(User, null=True, on_delete=models.CASCADE)
    date = models.DateField(auto_now_add=True, auto_now=False, blank=True)
    ...


"""I extended the User model with a Profile"""
@receiver(post_save, sender=User)
def create_user_profile(sender, instance, created, **kwargs):
if created:
    Profile.objects.create(user=instance)


@receiver(post_save, sender=User)
def save_user_profile(sender, instance, **kwargs):
     instance.profile.save()


"""and here is the mail sending signal"""
@receiver(post_save, sender=User)
def send_new_user_data_email(sender, instance, created, **kwargs):

# if a new user is created, compose and send the email
    if created:
        username = instance.username
    
        subject = 'Subject line'
        message = 'User: {0}\nPassword: ... \nblablabla'.format(username)
    
        send_mail(
            subject,
            message,
            '[email protected]',
            ['[email protected]', '[email protected] ', '{0}'],
            fail_silently=False,
        )

Upvotes: 1

Views: 391

Answers (1)

willeM_ Van Onsem
willeM_ Van Onsem

Reputation: 477543

You can access the fields from the instance saved:

@receiver(post_save, sender=User)
def send_new_user_data_email(sender, instance, created, **kwargs):
    if created:
        username = instance.username
    
        subject = 'Subject line'
        message = f'User: {instance.username}\nPassword: ... \nblablabla'
    
        send_mail(
            subject,
            message,
            None,
            [instance.email],
            fail_silently=False,
        )

In fact you do not need to save the instance first, you can send the email before saving it to the database:

from django.db.models.signals import pre_save

@receiver(pre_save, sender=User)
def send_new_user_data_email(sender, instance, created, **kwargs):
    # …
    pass

The email field of Django's builtin user model is not required (it has blank=True), so it is possible that the user is created without an email address. If you want to alter that, you should make a slight modification to the form used by the ModelAdmin for that User model.

Upvotes: 1

Related Questions