Django异步发送注册激活邮件

记录一下Django发送异步邮件的过程

整个项目目录如下图所示
homework为整个项目的名称,t06为app名称

在这里插入图片描述

1、分别在homework和t06下的__init__文件中的配置

from __future__ import absolute_import
# 使用异步的参数
from .celery import app as celery_app

# python使用mysql的必备参数
import pymysql
pymysql.install_as_MySQLdb()
import pymysql
pymysql.install_as_MySQLdb()

2、在settings.py文件中的部分配置

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    't06',
    # 在INSTALL_APPS中需加入djcelery模块(必须)
    'djcelery'
]

#1、数据库连接
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',#引擎此处采用mysql的
        'NAME': '要连接的数据库的名字',#name即数据库的名字,
        'PORT': 3306,#mysql数据的端口,默认为3306
        'HOST': "地址",#“host”即主机地址
        'USER': "用户名", #“USER”指的是数据库注册用户名
        'PASSWORD': '数据库密码'#数据库的密码

    }
}

#2、缓存设置,主要用来记录激活邮件中发送的信息
SESSION_COOKIE_NAME = "session_id"
#此处采用Redis来存储缓存信息
CACHES = {
	#此处为默认选择
    "default": {
        "BACKEND": "django_redis.cache.RedisCache",
        "LOCATION": "redis://127.0.0.1:6379/1",
        "OPTIONS": {
            "CLIENT_CLASS": "django_redis.client.DefaultClient",
        }
    },
    #此处为自定义选择
    "user": {
        "BACKEND": "django_redis.cache.RedisCache",
        "LOCATION": "redis://127.0.0.1:6379/2",
        "OPTIONS": {
            "CLIENT_CLASS": "django_redis.client.DefaultClient",
        }
    },
}

#3、邮件发送者的配置
EMAIL_USE_SSL = True
EMAIL_HOST = 'smtp.qq.com'  # 如果是 163 改成 smtp.163.com
EMAIL_PORT = 465
EMAIL_HOST_USER = "xxxxxxxxx@qq.com"  # 发送者的帐号
EMAIL_HOST_PASSWORD = "授权码"  # 授权码,不是邮箱密码(****)
DEFAULT_FROM_EMAIL = EMAIL_HOST_USER


#4、异步执行的配置,需要导入djcelery模块
import djcelery
djcelery.setup_loader()
BROKER_URL = 'redis://localhost:6379/1'
CELERY_CONCURRENCY = 2  # (设置worker的并发数量)
CELERY_RESULT_BACKEND = 'redis://localhost:6379/2'
CELERY_TASK_SERIALIZER = 'json'  # 任务序列化和反序列化使用json
CELERY_RESULT_SERIALIZER = 'json'  # 结果序列化为json

CELERYBEAT_SCHEDULE = {
    'every-ten-second-run-my-task': {
        'task': 't06.tasks.my_task',#task程序的位置
        'schedule': timedelta(seconds=10),
        'args': (2,)
    },
}

3、在celery.py文件中的配置

# -*- coding: utf-8 -*-
from __future__ import absolute_import #绝对路径导入
from celery import Celery
import os

#设置系统的环境配置用的是Django的
from django.conf import settings
os.environ.setdefault("DJANGO_SETTING_MODULE", "homework.settings")

#实例化celery
app = Celery('mycelery')

app.conf.timezone = "Asia/Shanghai"

#指定celery的配置来源 用的是项目的配置文件settings.py
app.config_from_object("django.conf:settings")

#让celery 自动去发现我们的任务(task)
app.autodiscover_tasks(lambda : settings.INSTALLED_APPS) #你需要在app目录下 新建一个叫tasks.py(一定不要写错)文件y

4、在tasks.py文件中的配置(文件名必须为tasks,是celery文件中规定的)

# -*- coding: utf-8 -*-
from celery import task
import time
from django.conf import settings
from django.core.mail import send_mail
from django.http import HttpResponse
from django.template.loader import get_template


@task
def send_my_mail(title,message,email):
    email_from = settings.DEFAULT_FROM_EMAIL
    recivies = [
        email
    ]
    url = message
    # 渲染
    template = get_template('temp.html')
    html_str = template.render({'url':url})
    print(html_str)
    #发送邮件的函数,Django中自带
    send_mail(
        title,message,email_from,recivies
    )
    return HttpResponse('ok')

5、在views.py文件中的执行注册激活功能的函数
register函数用于生成验证链接并发送邮件,index函数用于激活用户

其中get_user,MyUser,get_unique_name,send_my_mail(即task.py文件中的函数)均为自定义表或函数

# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from .tasks import *

from django.contrib.auth import authenticate, login, logout, update_session_auth_hash
from django.http import HttpResponse, HttpResponseNotAllowed, JsonResponse
from django.shortcuts import render,redirect
from django.urls import reverse
from .util import get_unique_name
from .models import MyUser
from django.core.cache import cache, caches


#设置使用的缓存,此处的“user”即为settings中CACHE中自定义的缓存容器
user_cache = caches["user"]
def index(req):
    if req.method =='GET':
        # 得到验证码
        verification = req.GET.get('verification')
        # print(message)
        uname = req.GET.get('uname')
        # print(uname)
        print(get_user(verification))
        if get_user(verification):
            user001 = MyUser.objects.filter(username=uname).update(
                is_active=True
            )
    data = req.POST.get('uname')
    if data == None:
        data={
            'uname':'游客'
        }
        return render(req,'index.html',{"error_msg":'欢迎游客'})


def register(req):
    if req.method =='GET':
        return render(req,'register.html',{'error_msg':''})
    elif req.method == 'POST':
        uname = req.POST.get('uname')
        print(uname)
        email = req.POST.get('email')
        phone = req.POST.get('phone')
        pwd = req.POST.get('pwd')
        print(pwd)
        confirm_pwd = req.POST.get('confirm_pwd')
        print('输入完成')
        # 验证用户名是否符合
        # 验证密码是否正确
        if uname and len(uname)<3:
            return render(req,'register.html',{'error_msg':'用户名长度至少为3'})
        elif  pwd and pwd == confirm_pwd:
            pass
        else:
            return render(req,'register.html',{'error_msg':'密码与确认密码不一致'})
        # 验证用户名,手机号,邮箱是否已存在
        if MyUser.objects.filter(username=uname).exists():
            return render(req,'register.html',{'error_msg':'用户名已存在'})
        elif MyUser.objects.filter(email=email).exists():
            return render(req,'register.html',{'error_msg':'邮箱已存在'})
        elif MyUser.objects.filter(phone=phone).exists():
            return render(req,'register.html',{'error_msg':'手机号已存在'})
        else:
            print('验证完毕')
            user = MyUser.objects.create_user(
                username=uname,
                password=pwd,
                phone = phone,
                email=email,
                is_active = False
            )

            # 注册同时生成激活邮件
            title = '验证邮件'
            schema = "https://" if req.is_secure() else "http://"
            verification = str(get_unique_name())
            # 设置缓存
            user_cache.set(verification, uname, 60 * 60)
            url_path = "/t06/index?verification="+verification+'&&uname='+str(uname)
            #生成验证的链接
            url_message = "{schema}{host_and_port}{url_path}".format(
                schema=schema,
                host_and_port=req.get_host(),
                url_path=url_path
            )
            send_my_mail.delay(title=title, message=url_message, email=email)

            return render(req,'index.html',{'error_msg':'注册成功,请激活邮件'})
    else:
        return render(req,'register,html',{'error_msg':''})

a、get_user函数,用于点击激活链接时查询缓存的操作,此处写在views.py文件下

def get_user(message):
    # 去缓存尝试拿数据
    res = user_cache.get(message)
    if res:
        print("缓存的")
        return True

b、get_unique_name函数,用于生成独一无二的验证码,此处写在views.py文件下

import random
import uuid
import hashlib

def get_unique_name():
    uuid_str = str(uuid.uuid4()).encode('utf-8')

    md5 = hashlib.md5()

    md5.update(uuid_str)

    return md5.hexdigest().lower()

c、自定义的MyUser用户表,写在models.py文件下

# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.contrib.auth.models import AbstractUser
from django.db import models
#继承了Django自带的user表
class MyUser(AbstractUser):
    phone = models.CharField(
        max_length=13,
        verbose_name='手机号',
        unique=True,
        null=True
    )
    email = models.EmailField(
        null=False
    )

启动程序
1、在manage.py文件所在目录下启动程序
python manage.py runserver 0.0.0.0:9000

2、启动异步的程序(一定要启动!!!!!!!!!!!!!!)
python manage.py celery worker --loglevel=info


补充
由于自定义了用户表,所以验证函数authenticate也需要重新定义,此处写在auth.py文件中

# -*- coding: utf-8 -*-
from django.contrib.auth.backends import ModelBackend
from .models import MyUser


class MyBackend(ModelBackend):
    def authenticate(self, request, username=None, password=None, phone =None,email=None):
        if not password:
            return Exception('密码必须填写')
        user = None
        try:
            user = MyUser.objects.get(username=username)
        except MyUser.DoesNotExist:
            try:
                user = MyUser.objects.get(phone=username)
            except MyUser.DoesNotExist:
                # try:
                #     user=MyUser.objects.get(email=username)
                # except MyUser.DoesNotExist:
                    return None
        if user and user.check_password(password) and user.is_active:
            return user
        else:
            return None
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值