周末大作业

周末大作业

1.编写登录/注册接口

  • 后台代码

views.py

# register
from rest_framework.viewsets import ViewSetMixin
from .serializer import RegisterSerializer, LoginSerializer
from luffyapi.utils.apiresponse import APIResponse

from .models import User

class RegisterView(ViewSetMixin, GenericAPIView):
    serializer_class = RegisterSerializer

    def perform_create(self, serializer):
        serializer.save()

    def register(self, request, *args, **kwargs):
        serializer = self.get_serializer(data=request.data)
        serializer.is_valid(raise_exception=True)
        self.perform_create(serializer)
        return APIResponse(msg='用户注册成功', data=serializer.data)

# login
    
class LoginView(ViewSetMixin, APIView):

    def login(self, request, *args, **kwargs):
        serializer = LoginSerializer(data=request.data, context={})
        serializer.is_valid(raise_exception=True)
        return APIResponse(msg='用户登录成功', data=serializer.context)

serializer.py

from rest_framework import serializers
from rest_framework.exceptions import ValidationError
from rest_framework_jwt.utils import jwt_payload_handler, jwt_encode_handler
from .models import User

import re
import time


# RegisterSerializer
class RegisterSerializer(serializers.ModelSerializer):
    re_password = serializers.CharField(max_length=32, write_only=True)

    class Meta:
        model = User
        fields = ['username', 'password', 're_password', 'telephone', 'email']

    def validate_username(self, username):
        if username.startswith('sb') and username.endswith('sb'):
            raise ValidationError("username中包含敏感词'sb'")
        if User.objects.filter(username=username, is_delete=False):
            raise ValidationError('用户已存在')
        return username

    def validate_telephone(self, telephone):
        if not re.match(r'^1[3-9][0-9]{9}$', telephone):
            raise ValidationError('手机的格式非法')
        return telephone

    def validate_email(self, email):
        if not re.match(r'^[A-Za-z0-9u4e00-u9fa5]+@[a-zA-Z0-9_-]+(.[a-zA-Z0-9_-]+)+$', email):
            raise ValidationError('邮箱格式不正确')
        return email

    def validate(self, attrs):
        password = attrs.get('password', None)
        re_password = attrs.pop('re_password', None)
        if not re_password == password:
            raise ValidationError('两次密码输入不一致')
        return attrs

    def create(self, validated_data):
        instance = User.objects.create_user(**validated_data)
        return instance

# LoginSerializer
class LoginSerializer(serializers.ModelSerializer):
    username = serializers.CharField(max_length=32)

    class Meta:
        model = User
        fields = ['username', 'password']

    def validate(self, attrs):
        username = attrs.get('username', None)
        password = attrs.get('password', None)
        if re.match(r'^1[3-9][0-9]{9}$', username):
            user = User.objects.filter(telephone=username, is_delete=False).first()
        elif re.match(r'^[A-Za-z0-9u4e00-u9fa5]+@[a-zA-Z0-9_-]+(.[a-zA-Z0-9_-]+)+$', username):
            user = User.objects.filter(email=username, is_delete=False).first()
        else:
            user = User.objects.filter(username=username, is_delete=False).first()
        if not user:
            raise ValidationError('用户不存在')
        if not user.check_password(password):
            raise ValidationError('密码错误')
        payload = jwt_payload_handler(user)  # 放入user对象得到payload对象
        jwt_value = jwt_encode_handler(payload)  # 放入payload对象得到token
        login_info = {'username': user.username, 'login_time': time.strftime('%Y-%m-%d %H:%M:%S'), 'token': jwt_value}
        for attr, value in login_info.items():
            self.context[attr] = value
        return attrs
  • 前台搭建
# 组件化开发
(1)下载Ele框架
cnpm i element-ui -S
相当于 cnpm install element-ui --save

# 配置ElementUI到项目中

import ElementUI from 'element-ui';
import 'element-ui/lib/theme-chalk/index.css';
Vue.use(ElementUI);

# 中文文档官网
http://element-cn.eleme.io/#/zh-CN

router/index.js

import Register from "../components/Register";
import Login from "../components/Login";

Vue.use(VueRouter);

const routes = [
    {
        path: '/',
        name: 'Home',
        component: Home
    },
    {
        path: '/register',
        name: 'Register',
        component: Register
    },
    {
        path: '/login',
        name: 'Login',
        component: Login
    }
];

Register.Vue

<template>
    <div id="Register">
        <el-row>
            <el-col :span="8" :offset="8">
                <div style="color: green;text-align: center">
                    <h1>注册页面
                        <img src="../assets/register.png" alt="" style=" 25px;height: 25px">
                    </h1>
                </div>
            </el-col>
            <el-col :span="8" :offset="8">
                <el-form :model="formLabelRegister" label-width="80px">
                    <el-form-item label="用户名">
                        <el-input v-model="formLabelRegister.username" ></el-input>
                    </el-form-item>
                    <el-form-item label="密码">
                        <el-input v-model="formLabelRegister.password" prefix-icon="el-icon-key"
                                  show-password></el-input>
                    </el-form-item>
                    <el-form-item label="确认密码">
                        <el-input v-model="formLabelRegister.re_password" prefix-icon="el-icon-key"
                                  show-password></el-input>
                    </el-form-item>
                    <el-form-item label="手机号">
                        <el-input v-model="formLabelRegister.telephone" prefix-icon="el-icon-phone-outline"></el-input>
                    </el-form-item>
                    <el-form-item label="邮箱">
                        <el-input v-model="formLabelRegister.email"></el-input>
                    </el-form-item>
                    <el-form-item style="text-align: center">
                        <el-button type="primary" @click="register">注册账号</el-button>
                    </el-form-item>
                </el-form>
            </el-col>
        </el-row>
    </div>
</template>

<script>
    export default {
        name: "Register",
        data() {
            return {
                formLabelRegister: {
                    username: '',
                    password: '',
                    re_password: '',
                    telephone: '',
                    email: ''
                }
            }
        },
        methods: {
            register() {
                this.$axios({
                    url: 'http://127.0.0.1:8000/user/register/',
                    method: 'post',
                    data: JSON.stringify({
                        'username': this.formLabelRegister.username,
                        'password': this.formLabelRegister.password,
                        're_password': this.formLabelRegister.re_password,
                        'telephone': this.formLabelRegister.telephone,
                        'email': this.formLabelRegister.email
                    }),
                    headers: {
                        'Content-Type': 'application/json',
                    }
                }).then(response => {
                    console.log(response.data)
                }).catch(errors => {
                    console.log(errors)
                })
            }
        }
    }
</script>

<style scoped>

</style>

Login.vue

<template>
    <div id="Login">
        <el-row>
            <el-col :span="8" :offset="8">
                <div style="color: green;text-align: center">
                    <h1>登录界面
                        <img src="../assets/login.png" alt="" style=" 25px;height: 25px">
                    </h1>
                </div>
            </el-col>
            <el-col :span="8" :offset="8">
                <el-form :model="formLabelLogin" label-width="80px">
                    <el-form-item label="账号">
                        <el-input v-model="formLabelLogin.account" placeholder="用户名/手机号/邮箱"></el-input>
                    </el-form-item>
                    <el-form-item label="密码">
                        <el-input v-model="formLabelLogin.password" prefix-icon="el-icon-key"
                                  show-password></el-input>
                    </el-form-item>
                    <el-form-item style="text-align: center">
                        <el-button type="primary" @click="login">登录账号</el-button>
                    </el-form-item>
                </el-form>
            </el-col>
        </el-row>
    </div>
</template>

<script>
    export default {
        name: "Login",
        data() {
            return {
                formLabelLogin: {
                    account: '',
                    password: '',
                }
            }
        },
        methods: {
            login() {
                this.$axios({
                    url: 'http://127.0.0.1:8000/user/login/',
                    method: 'post',
                    data: JSON.stringify({
                        'username': this.formLabelLogin.account,
                        'password': this.formLabelLogin.password
                    }),
                    headers: {
                        'Content-Type': 'application/json',
                    }
                }).then(response => {
                    console.log(response.data)
                }).catch(errors => {
                    console.log(errors)
                })
            }
        }
    }
</script>

<style scoped>

</style>
原文地址:https://www.cnblogs.com/surpass123/p/13341659.html