简体   繁体   中英

I am sending registration activation email using celery in django but celery gives some error

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM