首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >从零搭建一个django项目-6-注册实现(上)

从零搭建一个django项目-6-注册实现(上)

作者头像
怪盗LYL
发布2022-06-13 13:20:06
发布2022-06-13 13:20:06
6930
举报
文章被收录于专栏:测试开发真货测试开发真货

今天来具体实现注册功能。

01

注册页面

首先简单写一个注册页面。

代码语言:javascript
复制
<template>
  <div class="bg">
    <div id="register">
      <h2>注册页面</h2>
      <el-form ref="form" :model="form" label-width="20%">
        <el-form-item label="用户名:">
          <el-input v-model="form.username"  placeholder="username" ></el-input>
        </el-form-item>
        <el-form-item label="密  码:">
          <el-input v-model="form.password" type="password"  placeholder="password" ></el-input>
        </el-form-item>
        <el-form-item label="邮 箱:">
          <el-input v-model="form.email"  placeholder="email"></el-input>
        </el-form-item>
        <el-form-item label="验证码:">
          <el-input v-model="form.emailcode" style="width: 49%;margin-right: 2%;"></el-input>
          <el-button type="primary"  style="width: 49%;"  @click="getcode">发送</el-button>
        </el-form-item>
      </el-form>
      <el-button type="primary" round @click="register" class="btn">注册</el-button>
    </div>
  </div>
</template>
<script>
import { ElMessage } from 'element-plus' // eslint-disable-line no-unused-vars
import axios from 'axios'
export default {
  data () {
    return {
      form: {
        username: '用户名',
        password: '密码',
        email: 'xxxx@xx.com',
        emailcode: ''  
      },
      isnull: false
    };
  },
  components: {   
  },
  methods: {
    register() {
      if (this.form.username == '') {
        this.$message.error('用户名不能为空');
      } else if (this.form.password == '') {
        this.$message.error('密码不能为空');
      } else if (this.form.emailcode == '') {
          this.$message.error('验证码不能为空');
        } else {
        axios.post('http://localhost:8000/api/register/', {
          params: {
            username: this.form.username,
            password: this.form.password
          }
        }).then(res => {
          if (res.data.status == 200) {    
            let self = this
            self.$confirm("注册成功", "是否返回登录页", {
            confirmButtonText: "确认",
            cancelButtonText: "取消",
            type:"success",
            distinguishCancelAndClose: false,    // 设置为true才会把右上角X和取消区分开来
            closeOnClickModal: false
            }).then(function () {
              self.$router.push('/')
            }).catch(function (e) {
              if (e == 'cancel') {  
                console.log("取消");
                }else if(e == 'close') {  
                console.log("取消");  
                }
            })
          } else if (res.data.status == 202) {
            let self = this
            self.$alert('用户名已存在', '注册失败', {
              confirmButtonText: '确定',
              callback: action => { // eslint-disable-line no-unused-vars
                this.form.username = '',
                  this.form.password = ''
              }
            })
          }  else if (res.data.status == 203) {
              let self = this
              self.$alert('验证码错误', '注册失败', {
                confirmButtonText: '确定',
                callback: action => { // eslint-disable-line no-unused-vars
                  this.form.emailcode = ''
                }
              })
            } else {
            console.log(res.data.error);
          }
        }).catch(err => {
          console.log('操作失败' + err);
        })
      }
    }
  }
}
</script>

<style scoped>
.bg {
    position: absolute;
    top: 0;
    bottom: 0;
    left: 0;
    right: 0;
    background: url('../assets/login-bg3.jpg');
    background-size: 100% 100%;
}
 #register {
    min-height: 40%;
    width: 350px;
    box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.25);
    background: #ffffff;
    opacity: 0.85;
    position: absolute;
    top: 20%;
    left: 40%;
    text-align: center;
    display: flex;
    flex-direction: column;/*横向*/
    padding: 30px;
  }
  #register h2 {
    padding-bottom: 30px;
  }
  .btn {
    width: 60%;
    margin: auto;
  }
</style>

点击注册,控制台报错Access to XMLHttpRequest at 'http://localhost:8000/api/register/' from origin 'http://localhost:8081' has been blocked by CORS policy:

这个是跨域的问题。我们修改下请求地址:

从axios.post('http://localhost:8000/api/register/', {

改成axios.post('/api/register/', {

然后打包使用pycharm启动项目,嘿嘿不报错了,但是调试时候我们不能每次都打包吧,所以可以修改下设置。

修改setting文件:

代码语言:javascript
复制
MIDDLEWARE = [
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'corsheaders.middleware.CorsMiddleware',
    'django.middleware.common.CommonMiddleware',
    # 'django.middleware.csrf.CsrfViewMiddleware', #禁用csrf校验
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
]

修改回请求,再次开发运行,也不报错了,这样因为跨域校验去掉了。

02

调试接口连通性

页面有了我们看下注册接口。myapp下面的url文件添加路径:

代码语言:javascript
复制
re_path(r'^register/$', register.as_view(), name="api"

新建视图类:这里只是先简单的获取下请求值以判断是否能获取到前端传值。

代码语言:javascript
复制
class register(APIView):
    def post(self, request, *args, **kwargs):
        # 如果headerkey为auth - token,即headers = {'auth-token': '1234'}
        # 应该使用request.META.get("HTTP_AUTH_TOKEN")
        # 获取 headerkey中的小写转为大写,横线“-”转为下划线“_”, 并且加上前缀HTTP
        # 尤其注意headerkey中不应该包含HTTP前缀,以及符号"_", 否则会取不到对应的值
        # params用于获取字符串,
        # data:用于获取正文,
        # post方法两个参数都可以使用,get方法只能使用params
        print(request.META.get("HTTP_AUTH_TOKE",'321'))
        print(request.data)
        payload={'status': "200", 'message': "注册成功"}
        return Response(payload)

前端到后端是通的。

03

邮箱验证码的实现

首先修改页面:

默认参数新增:

代码语言:javascript
复制
        time: 0,
        yzm_disabled: false,
        yzm_txt: "获取验证码",

调用sendcode函数:

代码语言:javascript
复制
        <el-form-item label="验证码:">
          <el-input v-model="form.emailcode" style="width: 49%;margin-right: 2%;"></el-input>
          <el-button type="primary" :disabled=yzm_disabled style="width: 49%;" @click="sendcode">{{yzm_txt}}
          </el-button>
        </el-form-item>
代码语言:javascript
复制
,
      sendcode() {
        var regEmail = /^[a-zA-Z0-9_-]+([-_.][a-zA-Z0-9_-]+)*@([a-zA-Z0-9_-]+[-.])+[a-zA-Z0-9_-]{2,5}$/;
        if (this.form.email == '') {
          alert("请输入邮箱");
        } else if (!regEmail.test(this.form.email)) {
          alert("邮箱格式不正确");
        } else {
          this.time = 60;
          this.yzm_disabled = true;
          this.timer();
          axios.post('http://localhost:8000/api/sendcode/', {
              email: this.form.email
          }).then(res => {
            console.log('发送成功'+res);
          }).catch(err => {
            console.log('操作失败' + err);
          })
        }
      },
      timer() {
        if (this.time > 0) {
          this.time--;
          this.yzm_txt = this.time + "s后重新获取";
          setTimeout(this.timer, 1000);
        } else {
          this.time = 0;
          this.yzm_txt = "获取验证码";
          this.yzm_disabled = false;
        }
      }
    }

编写邮箱工具类的方法:

代码语言:javascript
复制
#-*- codeing = utf-8 -*-
#@Time: 2022/5/29 20:54
#@Author: 怪盗LLYL
#@File: sendemail.py
#@Software: PyCharm
from email.header import Header
from email.mime.text import MIMEText
from email.utils import parseaddr, formataddr
from django_wx import  settings
import smtplib
class MyEmail(object):
    def sendemail(self,code,to_addr):
        def _format_addr(s):
            name, addr = parseaddr(s)
            return formataddr((Header(name, 'utf-8').encode(), addr))

        from_addr = settings.SEND_EMAIL# 发邮件的邮箱
        password = settings.EMAIL_PASSWORD#授权码
        to_addr =  to_addr #目标
        smtp_server ='smtp.163.com'# input('SMTP server: ')
        msg = MIMEText('<html><body><p>验证码:'  + code  +  '</p>' +    '</body></html>', 'html', 'utf-8')
        msg['From'] = _format_addr('测试开发真货 <%s>' % from_addr)
        msg['To'] = _format_addr('登录用户 <%s>' % to_addr)
        msg['Subject'] = Header('登录验证码', 'utf-8').encode() #邮件主题
        server = smtplib.SMTP(smtp_server, 25)
        server.set_debuglevel(1)
        server.login(from_addr, password)
        server.sendmail(from_addr, [to_addr], msg.as_string())
        server.quit()
if __name__ == '__main__':
    myemai = MyEmail()
    myemai.sendemail('qwea','xxxxx@qq.com')

发送邮件需要打开服务,我用的是163的邮箱,需要打开SMTP服务,和获取授权码,其他邮箱同理。

增加路由和发验证码方法,修改注册方法

代码语言:javascript
复制
class sendcode(APIView):
    def post(self, request, *args, **kwargs):
        email = request.data['email']
        code_list = []
        for i in range(6):  # 控制验证码的位数
            state = random.randint(1, 3)  # 生成状态码
            if state == 1:
                first_kind = random.randint(65, 90)  # 大写字母
                random_uppercase = chr(first_kind)
                code_list.append(random_uppercase)
            elif state == 2:
                second_kinds = random.randint(97, 122)  # 小写字母
                random_lowercase = chr(second_kinds)
                code_list.append(random_lowercase)
            elif state == 3:
                third_kinds = random.randint(0, 9)
                code_list.append(str(third_kinds))
        emailcode = "".join(code_list)
        myemail = MyEmail()
        myemail.sendemail(emailcode,email)
        request.session['emailcode'] = emailcode
        payload={'status': "200", 'message': "发送成功"}
        return Response(payload)
代码语言:javascript
复制
class register(APIView):
    def post(self, request, *args, **kwargs):
        # 如果headerkey为auth - token,即headers = {'auth-token': '1234'}
        # 应该使用request.META.get("HTTP_AUTH_TOKEN")
        # 获取 headerkey中的小写转为大写,横线“-”转为下划线“_”, 并且加上前缀HTTP
        # 尤其注意headerkey中不应该包含HTTP前缀,以及符号"_", 否则会取不到对应的值
        # params用于获取字符串,
        # data:用于获取正文,
        # post方法两个参数都可以使用,get方法只能使用params
        # print(request.META.get("HTTP_AUTH_TOKE",'321'))
        emailcode = request.data["emailcode"]
        print(emailcode)
        print(request.session.get('emailcode', None))
        if emailcode == request.session.get('emailcode', None):
            payload={'status': "200", 'message': "注册成功"}
        else:
            payload = {'status': "203", 'error': "验证码不正确"}
        return Response(payload)

注意:这里用到了session储存验证码,需要在前端启用。

输入错误验证码:

输入正确验证码:

04

预告

今天先到这吧,下一节我们将创建一个用户视图模型,并再注册时候新建用户记录,工作日更新会慢。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2022-05-29,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 测试开发真货 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档