45 – Project-07- Send activation email

1. Send email directly

May cause page delay and remain stuck on the registration page

1. settings.py for sender configuration
# Send email configuration
EMAIL_BACKEND='django.core.mail.backends.smtp.EmailBackend',
#Mail server for smtp service
EMAIL_HOST = 'smtp.163.com'
# The fixed port of the smtp service is 25/625
EMAIL_PORT = 25
# Email address for sending emails
EMAIL_HOST_USER = '[email protected]'
# Client authorization password set in the mailbox
EMAIL_HOST_PASSWORD = 'XXXX' # How to get the authorization code of 163 mailbox on Baidu
# The sender seen by the recipient "This must be the same as the email address that sent the email>
EMAIL_FROM = 'python<[email protected]>'
2. Registration class Send email
#Send emails in the registration class

from django.core.mail import send_mail
from itsdangerous import TimedJSONWebSignatureSerializer as Serializer, SignatureExpired
from django.conf import settings

class RegisterView(View):
    """register"""

    def get(self, request):
        """Show registration page"""
        ...

    def post(self, request):
        """Perform registration processing"""
        # 1. Receive data
        ...
        # 2. Perform verification
        ...

        # 3. Carry out business processing: perform user registration
        ...
        user.save() # Additional save


        # Encrypt user’s identity information and generate activation token
        # Encrypted object (random string, expiration time (seconds))
        seriaizer = Serializer(settings.SECRET_KEY, 3600)
        info = {'confirm': user.id}
        token = seriaizer.dumps((info)) #dumps: encrypted, bytes type
        token = token.decode() # Decoding: default utf8

        # send email
        subject='Daily Fresh Welcome Message'
        message = ''
        sender = settings.EMAIL_FROM # Sender
        receiver = [email] # recipient
        # Contains html content, which needs to be escaped using the html_message parameter, otherwise it will be output as a string.
        html_message = '<h1>%s, you are welcome to be a registered member of Tiansheng Fresh</h1> Please click the link below to activate your account<br/><a href="http://127.0.0.1:8000/user /active/%s">http://127.0.0.1:8000/user/active/%s</a>'%(username,token,token)

        send_mail(subject,message,sender,receiver,html_message=html_message)

        # 4. Return the response and jump to the homepage
        ...

2. Celery sends emails asynchronously (recommended)


1. Install third-party libraries
pip install celery==4.4.7

pip install redis==3.2
2. Create asynchronous email file
# Create new apps/celery_tasks/tasks.py

# Use celery
import time
from celery import celery

#Add these sentences on the task handler side
# import django
# import os
# # django file initialization
# os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'django20.settings')
#django.setup()

# You don’t need to add these sentences when starting the project

#Create an instance object of the Celery class
from django.conf import settings
from django.core.mail import send_mail

# (Name: usually write path, broker=middleman)
app = Celery('celery_tasks.tasks',broker='redis://192.168.37.151:6379/8')


#Define task function
@app.task
def send_register_activeer_email(to_email,username,token):
    """Send activation email"""
    # Organize email messages
    subject = 'Daily Fresh Welcome Message'
    message = ''
    sender = settings.EMAIL_FROM # Sender
    receiver = [to_email] # Recipient
    # Contains html content, which needs to be escaped using the html_message parameter, otherwise it will be output as a string.
    html_message = '<h1>%s, you are welcome to be a registered member of Tiansheng Fresh</h1> Please click the link below to activate your account<br/><a href="http://127.0.0.1:8000/user /active/%s">http://127.0.0.1:8000/user/active/%s</a>' % (
    username, token, token)

    send_mail(subject, message, sender, receiver, html_message=html_message)
    time.sleep(5)
3. Register class to call asynchronous file
from apps.celery_tasks.tasks import send_register_activeer_email


class RegisterView(View):
    """register"""

    def get(self, request):
        """Show registration page"""
        ...

    def post(self, request):
        """Perform registration processing"""
        # 1. Receive data
        ...

        # 2. Perform verification
        ...

        # 3. Carry out business processing: perform user registration
        ...
        user.save() # Additional save


        # Encrypt user’s identity information and generate activation token
        # Encrypted object (random string, expiration time (seconds))
        seriaizer = Serializer(settings.SECRET_KEY, 3600)
        info = {'confirm': user.id}
        token = seriaizer.dumps((info)) #dumps: encrypted, bytes type
        token = token.decode() # Decoding: default utf8

        # Send email asynchronously
        # .delay is placed in the task queue (function parameters, x, x)
        send_register_activeer_email.delay(email,username,token)


        # 4. Return the response and jump to the homepage
        ...
4. Start the task handler

The middleman redis is on the virtual machine (centos7), soStart the processor in the virtual machine

The processor also needs the project code. Copy a copy to linux

If the local asynchronous file code changes, the file code on the virtual machine also needs to be modified

(1). Copy the project to the virtual machine

(2). Create a virtual environment – install dependency packages
# contos virtual environment Search on Baidu by yourself

# Generate dependency package files on widows
pip freeze > requirements.txt


# Download dependency packages on the virtual machine
pip install -r requirements.txt -i https://pypi.tuna.tsinghua.edu.cn/simple/

# When installing, an error message is reported: "WARNING: Running pip as the 'root' user can result in broken permissions and conflicting behavior with the system package manager. It is recommended to use a virtual environment instead: https://pip.pypa.io /warnings/venv"

# solution
1. Install virtualenv

2. Execute there, and the virtual environment will be built there.
virtualenv myproject

3. Enter the virtual environment
source myproject/bin/activate

4. Use the following command to install dependent libraries in the virtual environment
pip install -r requirements.txt

5. When you are done, just run the following command to exit the virtual environment
deactivate
(3). Asynchronous file initialization django configuration file on the virtual machine

(4). Enter the project root directory of the virtual machine and start the processor
# Start the handler
# celery -A asynchronous file name worker -l info
celery -A apps.celery_tasks.tasks worker -l info

# Error: AttributeError: 'EntryPoints' object has no attribute 'get'
#Install the following dependency packages:
# pip install frozenlist==1.3.1 geopy==2.2.0 humanize==4.3.0 idna==3.3 importlib-metadata==4.12.0 jsonschema==4.9.0 korean_lunar_calendar==0.2.1 marshmallow==3.17. 0 pyOpenSSL==22.0.0 pyrsistent==0.18.1 python-dotenv==0.20.0 pytz==2022.2.1 selenium==4.4.0 simplejson==3.17.6 sniffio==1.2.0 trio==0.21. 0 urllib3==1.26.11 wsproto==1.1.0 zipp==3.8.1


# If the above installation is still not resolved, perform the following installation. The author can solve the problem after completing the above installation.
# pip install backoff==2.1.2 colorama==0.4.5 croniter==1.3.5 cryptography==37.0.4 email-validator==1.2.1 flask-compress==1.12 flask-migrate==3.1.0 aiohttp ==3.8.1 aiosignal==1.2.0 Mako==1.2.1 Babel==2.10.3
(5). Start successful style