43 - 项目-05- 注册基本逻辑

一. 注册基本逻辑

1. user子应用 定义 注册视图类
import re
from django.conf import settings
from django.http import HttpResponse
from django.shortcuts import render, redirect
from django.urls import reverse

# 显示异常,但不会报错
from django.views.generic import View
from user.models import User

class RegisterView(View):
    """注册"""

    def get(self, request):
        """显示注册页面"""
        return render(request, 'register.html')

    def post(self, request):
        """进行注册处理"""
        # 1. 接收数据
        username = request.POST.get('user_name')
        password = request.POST.get('pwd')
        email = request.POST.get('email')
        allow = request.POST.get("allow")  # 复选框,如果选择参数值就是 'on'

        # 2. 进行校验
        if not all([username, password, email]):  # all函数,参数是可迭代的,都为True,则为True
            # 数据不完整
            return render(request, 'register.html', {"errmsg": "消息不完整"})

        # 校验邮箱
        if not re.match(r'^[a-z0-9][\w.\-]*@[a-z0-9\-]+(\.[a-z]{2,5}){1,2}$', email):
            return render(request, 'register.html', {"errmsg": "邮箱格式不合法"})

        # 校验是否勾选协议
        if allow != 'on':
            return render(request, 'register.html', {"errmsg": "请同意协议"})

        # 校验用户名是否重复
        try:
            user = User.objects.get(username=username)
        except User.DoesNotExist:
            # 用户名不存在
            user = None
        if user:
            # 用户名已存在
            return render(request, 'register.html', {"errmsg": "用户名已存在"})

        # 3. 进行业务处理: 进行用户注册
        # 使用django的内置认证可以直接使用 create_user方法保存
        user = User.objects.create_user(username, email, password)  # 执行这句代码已经保存到数据库了
        user.is_active = 0  # 额外 设置账号未激活
        user.save()  # 额外 保存


        # 4. 返回应答,跳转到首页
        # reverse反向解析(主urls定义的别名 : 子url定义的别名)

        # return redirect(reverse('goods:index')) #此时还没首页,后面创建首页后自己放开注释
        return HttpResponse("首页")
2. user子应用定义 注册路由
from django.conf.urls import url
from apps.user import views
from apps.user.views import RegisterView

app_name="user" # 指定命名空间
urlpatterns = [
    url(r'^register$',RegisterView.as_view(),name="register"), # 注册
]
3. 注册页面源码

        正在补充

二. 用户激活

注册后,需要用户点击邮件中的链接账号才能生效

为了保证安全,需要对用户的身份信息加密

1. 安装第三方库
pip install itsdangerous==1.1
2. 生成 激活 用的token
# 在注册类中生成token
 
from django.conf import settings
from itsdangerous import TimedJSONWebSignatureSerializer as Serializer, SignatureExpired
 
 
class RegisterView(View):
    """注册"""
 
    def get(self, request):
        """显示注册页面"""
        ...
 
    def post(self, request):
        """进行注册处理"""
        # 1. 接收数据
        ...
        # 2. 进行校验
        ...
        # 3. 进行业务处理: 进行用户注册
        ...
        user.save()  # 额外 保存
 
        # 发送激活邮件,包含激活链接: http://127.0.0.1"8000/user/active/3
        # 激活链接中需要包含用户的身份信息,并且要把身份信息进行加密
 
        # 加密用户的身份信息,生成激活token
        # 加密对象( 随机字符串,过期时间(秒) )
        seriaizer = Serializer(settings.SECRET_KEY, 3600)
        info = {'confirm': user.id}
        toeken = seriaizer.dumps((info))  # dumps: 加密
 
        # 发邮件
 
        # 4. 返回应答,跳转到首页
        ...
3. user子应用定义 激活验证类
        (1). 定义激活类
class ActiveView(View):
    """用户激活"""
    def get(self,request,token):
        """进行用户激活"""
        # 进行解密,获取要激活的用户信息
        seriaizer = Serializer(settings.SECRET_KEY, 3600) # 随机字符串和过期时间要和加密时设置的一样
        try:
            info = seriaizer.loads(token) # 解密
            # 获取激活用户的id
            user_id= info["confirm"]
 
            # 根据id获取用户信息
            user = User.objects.get(id=user_id)
            user.is_active=1
            user.save()
 
            # 跳转到登录页面
            # return redirect(reverse('user:login')) # 登陆还没定义,后期自己放开
            return HttpResponse("登录页")
 
        except SignatureExpired as e:
            # 激活链接已过期
            return HttpResponse("激活链接已过期")
        (2). 定义激活路由
url(r'^active/(?P<token>.*)$',ActiveView.as_view(),name="active"), # 用户激活

三. 发送激活邮件

1. 直接发邮件(不推荐)

        可能会造成页面延迟,一直卡在注册页

        (1). settings.py配置发件人
# 发送邮件配置
EMAIL_BACKEND='django.core.mail.backends.smtp.EmailBackend',
# smtp服务的邮件服务器
EMAIL_HOST = 'smtp.163.com'
# smtp服务固定的端口是25 / 625
EMAIL_PORT = 25
# 发送邮件的邮箱
EMAIL_HOST_USER = 'a123@163.com'
# 在邮箱中设置的客户端授权密码
EMAIL_HOST_PASSWORD = 'XXXX' # 自行百度查看163邮箱的授权码怎么获取
# 收件人看到的发件人《此处要和发送邮件的邮箱相同>
EMAIL_FROM = 'python<a123@163.com>'
        (2). 注册类 发送邮件
#再注册类中发送邮件
 
from django.core.mail import send_mail
from itsdangerous import TimedJSONWebSignatureSerializer as Serializer, SignatureExpired
from django.conf import settings
 
class RegisterView(View):
    """注册"""
 
    def get(self, request):
        """显示注册页面"""
        ...
 
    def post(self, request):
        """进行注册处理"""
        # 1. 接收数据
        ...
        # 2. 进行校验
        ...
 
        # 3. 进行业务处理: 进行用户注册
        ...
        user.save()  # 额外 保存
 
 
        # 加密用户的身份信息,生成激活token
        # 加密对象( 随机字符串,过期时间(秒) )
        seriaizer = Serializer(settings.SECRET_KEY, 3600)
        info = {'confirm': user.id}
        token = seriaizer.dumps((info))  # dumps: 加密, bytes类型
        token = token.decode() # 解码: 默认utf8
 
        # 发邮件
        subject='天天生鲜欢迎信息'
        message = ''
        sender = settings.EMAIL_FROM # 发件人
        receiver = [email] # 收件人
        # 包含html内容,需要使用html_message参数进行转义,否则就会当成字符串原样输出
        html_message = '<h1>%s, 欢迎您称为天天生鲜注册会员</h1>请点击下面链接激活您的账户<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. 返回应答,跳转到首页
        ...

2. celery异步发邮件(推荐)

        (1). 安装第三方库
pip install celery==4.4.7
 
pip install redis==3.2
        (2). 创建异步发邮件文件
# 新建 apps / celery_tasks / tasks.py
 
# 使用celery
import time
from celery import Celery
 
# 在任务处理者一端加这几句
# import django
# import os
# # django文件初始化
# os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'django20.settings')
# django.setup()
 
# 启动项目端不需要加这几句
 
# 创建一个Celery类的实例对象
from django.conf import settings
from django.core.mail import send_mail
 
# (名字:一般都写路径, broker=中间人)
app = Celery('celery_tasks.tasks',broker='redis://192.168.37.151:6379/8')
 
 
# 定义任务函数
@app.task
def send_register_activer_email(to_email,username,token):
    """发送激活邮件"""
    # 组织邮件信息
    subject = '天天生鲜欢迎信息'
    message = ''
    sender = settings.EMAIL_FROM  # 发件人
    receiver = [to_email]  # 收件人
    # 包含html内容,需要使用html_message参数进行转义,否则就会当成字符串原样输出
    html_message = '<h1>%s, 欢迎您称为天天生鲜注册会员</h1>请点击下面链接激活您的账户<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). 注册类调用异步文件
from apps.celery_tasks.tasks import send_register_activer_email
 
 
class RegisterView(View):
    """注册"""
 
    def get(self, request):
        """显示注册页面"""
        ...
 
    def post(self, request):
        """进行注册处理"""
        # 1. 接收数据
        ...
 
        # 2. 进行校验
        ...
 
        # 3. 进行业务处理: 进行用户注册
        ...
        user.save()  # 额外 保存
 
 
        # 加密用户的身份信息,生成激活token
        # 加密对象( 随机字符串,过期时间(秒) )
        seriaizer = Serializer(settings.SECRET_KEY, 3600)
        info = {'confirm': user.id}
        token = seriaizer.dumps((info))  # dumps: 加密, bytes类型
        token = token.decode() # 解码: 默认utf8
 
        # 异步发邮件
        # .delay放到任务队列(函数参数,x,x)
        send_register_activer_email.delay(email,username,token)
 
 
        # 4. 返回应答,跳转到首页
        ...
        (4). 启动任务处理者

        中间人redis在 虚拟机(centos7)上,所以在虚拟机启动处理者

         处理者也需要项目的代码. 复制一份到 linux 上

         如果本地异步文件代码改动, 虚拟机上的文件代码也需要修改

          ①. 复制项目到虚拟机

          ②. 创建虚拟环境- 安装依赖包

# contos 虚拟环境 自行百度搜索
 
# widows上 生成依赖包文件
pip freeze > requirements.txt
 
 
# 虚拟机上下载依赖包
pip install -r requirements.txt -i https://pypi.tuna.tsinghua.edu.cn/simple/
 
# 安装时报错:报错"WARNING: Running pip as the 'root' user can result in broken permissions and conflicting behaviour with the system package manager. It is recommended to use a virtual environment instead: https://pip.pypa.io/warnings/venv"
 
# 解决方案
1. 安装 virtualenv
 
2. 在那执行,虚拟环境就建在那
virtualenv myproject
 
3.进入虚拟环境
source myproject/bin/activate
 
4.在虚拟环境中使用以下命令安装依赖库
pip install -r requirements.txt
 
5.当您完成时,只需运行以下命令退出虚拟环境
deactivate

          ③. 虚拟机上异步文件 初始化 django配置文件

          ④. 进入虚拟机的 项目根目录,启动处理者

# 启动处理者
# celery -A 异步文件名 worker -l info
celery -A apps.celery_tasks.tasks worker -l info
 
# 报错:AttributeError: 'EntryPoints' object has no attribute 'get'
# 安装以下依赖包:
# 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
 
 
# 如果上述安装仍未解决,则执行以下安装,笔者执行完上述安装即能解决问题
# 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

          ⑤. 启动成功样式

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值