问题
I've built a site that requires membership for some portions. It's a club website so to be a member on the website, you have to be a member in real life. The plan is to have somebody from the Club check for new members (I'll probably have the system send them an email when a user signs up) and then the admin checks the active
checkbox under the user's record in the Django admin and saves the user.
The problem I'm trying to overcome is we need new, valid users to be notified as to when they can start using their account. Obviously manually sending an email is cumbersome.
Is there a way to hook into the save()
logic, check if the record's active
state has changed, and if it has been activated, send that user an email telling them they can now log in?
I'm on top of all the email logic, I just need to know where to put it.
I realise there are other ways of testing (check for last_login==None
on active==True
accounts on a cron-style job) but I'd like notifications to be near-enough instant.
回答1:
Yes, you need to use django signals, specifically post_save(). This, as you probably guessed, get's called after the save of your model and you can then implement whatever post save functionality (that is, post write to the database) you require.
回答2:
ok 5 years latter but this works for me with django 1.8 and python 2.7
The context is: the user create a new account then the admin receives an email to verify the user and chage active to True when the admin makes the change the user receives an email telling that now he can log in.
Sorry for my bad english.
#forms.py
from django import forms
from django.contrib.auth.forms import UserCreationForm
from django.contrib.auth.models import User
#A register form that save field is_active as False
class RegisterForm(UserCreationForm):
email = forms.EmailField(label=_("E-mail"))
first_name = forms.CharField(label=_("First Name"))
last_name = forms.CharField(label=_("Last Name"))
is_active = forms.BooleanField(required=False, initial=False, label=_("Activo"), widget=forms.HiddenInput())
class Meta:
model = User
fields = ('username','first_name','last_name','email','password1','password2','is_active')
def save(self, commit=True):
user = super(UserCreationForm, self).save(commit=False)
user.first_name = self.cleaned_data['first_name']
user.last_name = self.cleaned_data['last_name']
user.email = self.cleaned_data['email']
user.is_active = self.cleaned_data['is_active']
if commit:
user.save()
return user
I use the signals in models.py file but you can use it in a signals.py file
#models.py
from django.contrib.auth.models import User
from django.db.models import signals
from django.db import models
from django.dispatch import receiver
from django.db.models.signals import pre_save, post_save
from django.conf import settings
from django.core.mail import send_mail
#signal used for is_active=False to is_active=True
@receiver(pre_save, sender=User, dispatch_uid='active')
def active(sender, instance, **kwargs):
if instance.is_active and User.objects.filter(pk=instance.pk, is_active=False).exists():
subject = 'Active account'
mesagge = '%s your account is now active' %(instance.username)
from_email = settings.EMAIL_HOST_USER
send_mail(subject, mesagge, from_email, [instance.email], fail_silently=False)
#signal to send an email to the admin when a user creates a new account
@receiver(post_save, sender=User, dispatch_uid='register')
def register(sender, instance, **kwargs):
if kwargs.get('created', False):
subject = 'Verificatión of the %s account' %(instance.username)
mesagge = 'here goes your message to the admin'
from_email = settings.EMAIL_HOST_USER
send_mail(subject, mesagge, from_email, [from_email], fail_silently=False)
回答3:
This has not been tested but here is a modified version of something I do that is similar:
from django.contrib.auth.models import User
from django.db.models import signals
from django.conf import settings
from django.core.mail import send_mail
def pre_user_save(sender, instance, *args, **kwargs):
if instance.active != User.objects.get(id=instance.id).active:
send_mail(
subject='Active changed: %s -> %s' % (instance.username, instance.active),
message='Guess who changed active status??',
from_email=settings.SERVER_EMAIL,
recipient_list=[p[1] for p in settings.MANAGERS],
)
signals.pre_save.connect(pre_user_save, sender=User, dispatch_uid='pre_user_save')
Hope this helps!
来源:https://stackoverflow.com/questions/4451275/send-an-email-if-to-a-django-user-if-their-active-status-is-changed