周末大作业
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>