I am sending a registration activation email using celery in Django. forms.py
from django import forms
from .models import User
from django.contrib.auth.forms import UserCreationForm, AuthenticationForm
from .tasks import send_confirmation_mail_task
from django.conf import settings
from phonenumber_field.formfields import PhoneNumberField
from django.contrib.auth.forms import PasswordResetForm as PasswordResetFormCore
class RegisterForm(UserCreationForm):
first_name = forms.CharField(required = True)
last_name = forms.CharField(required = True)
mobile_no = PhoneNumberField(widget=forms.TextInput(attrs={'placeholder': '+91 8866776644'}))
date_of_birth = forms.DateField(input_formats=settings.DATE_INPUT_FORMATS, widget=forms.DateInput(attrs={'type': 'date', 'class':'datepicker'}))
class Meta:
model = User
fields = ('username', 'email', 'first_name', 'last_name', 'mobile_no', 'date_of_birth', 'address',
'password1', 'password2')
def send_email(self):
send_confirmation_mail_task.delay(
self.cleaned_data['username'], self.cleaned_data['email']
)
tasks.py
from __future__ import absolute_import, unicode_literals
from celery.decorators import task
from celery.utils.log import get_task_logger
from .email import send_confirmation_mail
from django.contrib.auth.forms import PasswordResetForm
logger = get_task_logger(__name__)
@task(name="send_confirmation_mail_task")
def send_confirmation_mail_task(username, email):
logger.info("Sent Confirmation Email")
return send_confirmation_mail(username, email)
email.py
from django.template import Context
from django.contrib.sites.shortcuts import get_current_site
from django.utils.encoding import force_bytes, force_text
from django.utils.http import urlsafe_base64_encode, urlsafe_base64_decode
from django.template.loader import render_to_string
from .tokens import account_activation_token
from django.core.mail import EmailMessage
from django.conf import settings
from django.contrib.sites.models import Site
from accounts.models import User
def send_confirmation_mail(username, email):
user = User.objects.filter(pk=user.id)
current_site = Site.objects.get_current().domain
message={
'username': username,
'email': email,
'domain': current_site,
'uid': urlsafe_base64_encode(force_bytes(user.pk)).decode(),
'token': account_activation_token.make_token(user),
}
email_subject = 'Activation Mail'
email_body = render_to_string('activation_mail.html', message)
email = EmailMessage(
email_subject, email_body,
settings.DEFAULT_FROM_EMAIL, [email, ],
)
return email.send(fail_silently=False)
[2020-11-04 10:33:41,794: INFO/MainProcess] mingle: searching for neighbors
[2020-11-04 10:33:42,814: INFO/MainProcess] mingle: all alone
[2020-11-04 10:33:42,826: WARNING/MainProcess] /home/rajpatel/Desktop/Projects/venv/lib/python3.5/site-packages/celery/fixups/django.py:202: UserWarning: Using settings.DEBUG leads to a memory leak, never use this setting in production environments!
warnings.warn('Using settings.DEBUG leads to a memory leak, never '
[2020-11-04 10:33:42,826: INFO/MainProcess] celery@kanan ready.
[2020-11-04 10:49:09,846: INFO/MainProcess] Received task: send_confirmation_mail_task[dd2658c8-cccb-4ad1-98d6-edcedea24a86]
[2020-11-04 10:49:09,848: INFO/ForkPoolWorker-3] send_confirmation_mail_task[dd2658c8-cccb-4ad1-98d6-edcedea24a86]: Sent Confirmation Email
[2020-11-04 10:49:09,850: ERROR/ForkPoolWorker-3] Task send_confirmation_mail_task[dd2658c8-cccb-4ad1-98d6-edcedea24a86] raised unexpected: UnboundLocalError("local variable 'user' referenced before assignment",)
Traceback (most recent call last):
File "/home/rajpatel/Desktop/Projects/venv/lib/python3.5/site-packages/celery/app/trace.py", line 374, in trace_task
R = retval = fun(*args, **kwargs)
File "/home/rajpatel/Desktop/Projects/venv/lib/python3.5/site-packages/celery/app/trace.py", line 629, in __protected_call__
return self.run(*args, **kwargs)
File "/home/rajpatel/Desktop/Projects/ecommerce/accounts/tasks.py", line 14, in send_confirmation_mail_task
return send_confirmation_mail(username, email)
File "/home/rajpatel/Desktop/Projects/ecommerce/accounts/email.py", line 13, in send_confirmation_mail
user = User.objects.filter(pk=user.id)
UnboundLocalError: local variable 'user' referenced before assignment
when i run celery -A ecommerce worker -l info
it gives above error. So how could i resolved this isssue? if you need more code i can reply it. there is more code.
also how to pass the user pk in email function which is out side of form.
in email.py
just remove the pk=user.id in the user variable
Before:
user = User.objects.filter(pk=user.id)
After:
user = User.objects.filter(username=username)
or
user = User.objects.filter(email=email)
Replace :
def send_confirmation_mail(username, email):
user = User.objects.filter(pk=user.id)
by
def send_confirmation_mail(username, email):
user = User.objects.filter(email=email)
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.