1、用户登录
用户名登录逻辑分析

用户名登录接口设计
请求方式

请求参数:表单

响应结果:HTML

用户名登录逻辑实现
用户后端验证视图文件apps/users/views.py
"""
"""
视图文件
apps/users/views.py文件,用户后端验证视图文件
"""
from django.shortcuts import render, redirect, reverse
from django.http import HttpResponse, JsonResponse
from django.views import View
from .forms import RegisterForm, LoginForm
from .models import User
from django.contrib.auth import login, authenticate # authenticate封装的验证用户名和密码是否正确的方法
from django_redis import get_redis_connection
# 用户登陆
class LoginView(View):
"""用户名登陆"""
def get(self, request):
""" 提供登陆界面
:return: 登陆界面
"""
return render(request, 'login.html')
def post(self, request):
"""
实现登录逻辑
:param request: 请求对象
:return: 登录结果
"""
# 接受参数
login_form = LoginForm(request.POST)
# 校验参数
if login_form.is_valid():
# 接收参数
username = login_form.cleaned_data.get('username')
password = login_form.cleaned_data.get('password')
remembered = request.POST.get('remembered') # 没经过form验证,使用request接收参数
# 认证登录用户
# users = User.objects.get(username=username)
# users.check_password(password) # check_password验证密码封装的方法,返回值bool类型
""" authenticate方法源码
def authenticate(self, request, username=None, password=None, **kwargs):
if username is None:
username = kwargs.get(UserModel.USERNAME_FIELD)
try:
user = UserModel._default_manager.get_by_natural_key(username)
except UserModel.DoesNotExist:
# Run the default password hasher once to reduce the timing
# difference between an existing and a nonexistent user (#20760).
UserModel().set_password(password)
else:
if user.check_password(password) and self.user_can_authenticate(user):
return user
"""
user = authenticate(username=username, password=password) # 重构authenticate方法之后,可以验证手机号登录和用户名登录
if user is None:
# 用户名或者密码输入错误
return render(request, 'login.html', {"errmsg": "用户名或者密码输入错误"})
# 实现状态保持
login(request, user)
# 设置状态保持的周期
if remembered != 'on':
# 没选中记住密码,浏览器关闭就需要销毁session信息
request.session.set_expiry(0) # set_expiry过期时间
else:
# 选中记住密码,session信息默认保存两周
# request.session.set_expiry(60*60*24*14)
request.session.set_expiry(None)
# 响应登录结果 跳转到首页
return redirect(reverse('contents:index'))
else:
print(login_form.errors.get_json_data())
context = {
"form_errors": login_form.errors,
}
return render(request, 'login.html', context=context)
class RegisterView(View):
"""用户注册"""
def get(self, request):
"""提供用户的注册界面"""
return render(request, 'register.html')
def post(self, request):
"""提供用户的注册逻辑"""
# 前端用户提交数据
form = RegisterForm(request.POST)
if form.is_valid():
# 接收参数
username = form.cleaned_data.get('username')
password = form.cleaned_data.get('password')
mobile = form.cleaned_data.get('mobile')
sms_code_client = request.POST.get('sms_code') # 验证短信验证码 sms_code是register.html 文件中命名的
# 判断用户输入的短信验证码是否正确
redis_conn = get_redis_connection('verify_code') # 链接redis中配置的数据库
sms_code_server = redis_conn.get('sms_%s' % mobile) # 根据存储时候的格式写
if sms_code_server is None:
return render(request, 'register.html', {'sms_code_errmsg': '短信验证码已经失效'}) # 错误信息渲染到前端界面
if sms_code_server.decode() != sms_code_client: # sms_code_server数据类型需要转换
return render(request, 'register.html', {'sms_code_errmsg': '短信验证码填写错误'})
try:
# user = User(username=username, password=password, mobile=mobile)
# 下面的添加数据的方法是封装了加密等功能的函数,更安全
users = User.objects.create_user(username=username, password=password, mobile=mobile)
except: # 如果保存数据失败
return render(request, 'register.html', {'register_error_message': '注册失败'})
# 保持用户登录的状态
login(request, users)
# 返回响应
# return HttpResponse('success')
return redirect(reverse('contents:index')) # 注册成功,跳转到首页
else:
print(form.errors.get_json_data())
# return HttpResponse("fail")
# 返回注册错误信息到前端界面
context = {
'form_error': form.errors,
}
return render(request, 'register.html', context=context)
class UsernameExists(View):
""" 判断用户名是否已经存在"""
def get(self, request, username): # username用户名
count = User.objects.filter(username=username).count() # 查询数据库中信息
return JsonResponse({"code": 0, "errmsg": "OK", "count": count}) # 返回给前端界面
后端表单验证文件:apps/users/forms.py ,验证登录的表单信息
# -*- encoding: utf-8 -*-
"""
@File : forms.py
@Time : 2020/7/28 16:16
@Author : chen
后端表单验证文件:apps/users/forms.py
"""
from django import forms
from .models import User
class RegisterForm(forms.Form): # 继承自forms.Form是只需要验证个别字段的信息,而继承自model.Form是需要验证所有的字段
username = forms.CharField(max_length=20, min_length=5, error_messages={"min_length": "用户名长度不对",
"max_length": "用户名长度不对"})
password = forms.CharField(max_length=20, min_length=8, error_messages={"min_length": "密码长度不对",
"max_length": "密码长度不对",
"required": "密码必须填写"})
password2 = forms.CharField(max_length=20, min_length=8, error_messages={"min_length": "密码长度不对",
"max_length": "密码长度不对",
"required": "密码必须填写"})
allow = forms.BooleanField()
mobile = forms.CharField(max_length=11, min_length=11, required=True, error_messages={"min_length": "手机号长度不对",
"max_length": "手机号长度不对",
"required": "手机号必须填写"})
sms_code = forms.CharField(max_length=6, min_length=6, required=True)
# 检测用户名是否已经在数据库中
def clean_username(self):
username = self.cleaned_data.get('username')
username_exists = User.objects.filter(username=username).exists() # 检查数据库中username是否存在
if username_exists:
raise forms.ValidationError('用户名已经存在')
return username
# 检测手机号是否已经在数据库中
def clean_mobile(self):
mobile = self.cleaned_data.get('mobile')
mobile_exists = User.objects.filter(mobile=mobile).exists() # 检查数据库中手机号是否存在
if mobile_exists:
raise forms.ValidationError('手机号已经存在')
return mobile
# 验证两次密码是否一致
def clean(self):
cleaned_data = super().clean() # 调用父类的clean方法
password = cleaned_data.get('password')
password2 = cleaned_data.get('password2')
if password != password2:
raise forms.ValidationError("两次密码不一致")
return cleaned_data # 可以不返回值,建议使用返回值
# 验证登录的表单信息
class LoginForm(forms.Form):
username = forms.CharField(max_length=20, min_length=5)
password = forms.CharField(max_length=20, min_length=8)
登陆前端界面:templates/login.html
{# 登陆前端界面:templates/login.html #}
{% load static %}
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html;charset=UTF-8">
<title>LG商城-登录</title>
<link rel="stylesheet" type="text/css" href="{% static 'css/reset.css' %}">
<link rel="stylesheet" type="text/css" href="{% static 'css/main.css' %}">
<script type="text/javascript" src="{% static 'js/vue-2.5.16.js' %}"></script>
<script type="text/javascript" src="{% static 'js/axios-0.18.0.min.js' %}"></script>
</head>
<body>
<div class="login_top clearfix">
<a href="index.html" class="login_logo"><img src="{% static 'images/2.png' %}"></a>
</div>
<div class="login_form_bg" id="app">
<div class="login_form_wrap clearfix">
<div class="login_banner fl"></div>
<div class="slogan fl">商品美 · 种类多 · 欢迎光临</div>
<div class="login_form fr">
<div class="login_title clearfix">
<a href="javascript:;" class="cur">账户登录</a>
</div>
<div class="form_con">
<div class="form_input cur">
<form method="post" class="login-form" @submit="on_submit" v-cloak>
{# {{ csrf_input }}#}
{% csrf_token %}
<input type="text" v-model="username" @blur="check_username" name="username" class="name_input" placeholder="请输入用户名或手机号">
<div v-show="error_username" class="user_error">请输入正确的用户名或手机号</div>
<input type="password" v-model="password" @blur="check_password" name="password" class="pass_input" placeholder="请输入密码">
<div v-show="error_password" class="pwd_error">密码最少8位,最长20位</div>
<div class="more_input clearfix">
<input type="checkbox" v-model="remembered" name="remembered">
<label>记住登录</label>
{# 这部分传注册错误信息到前端界面是用的Django自带的,前端验证form表单信息我们采用的是 @submit="on_submit" 中的ajax进行验证,这是两种方式,选择一种就可以 #}
{# 将apps/users/views.py文件中的登录错误信息context进行循环 #}
<span class="error_tip">
{% if form_errors %}
{% for key,error in form_errors.items %}
{{ error }}
{% endfor %}
{% endif %}
{# 保存用户登录数据失败的信息apps/users/views.py中传递的errmsg #}
{% if errmsg %}
{{ errmsg }}
{% endif %}
</span>
</div>
<input type="submit" value="登 录" class="input_submit">
</form>
</div>
</div>
<div class="third_party">
<a @click="qq_login" class="qq_login">QQ</a>
<a href="#" class="weixin_login">微信</a>
<a href="register.html" class="register_btn">立即注册</a>
</div>
</div>
</div>
</div>
<div class="footer no-mp">
<div class="foot_link">
<a href="#">关于我们</a>
<span>|</span>
<a href="#">联系我们</a>
<span>|</span>
<a href="#">招聘人才</a>
<span>|</span>
<a href="#">友情链接</a>
</div>
<p>CopyRight © 2016 北京商业股份有限公司 All Rights Reserved</p>
<p>电话:010-****888 京ICP备*******8号</p>
</div>
<script type="text/javascript" src="{% static 'js/common.js' %}"></script>
<script type="text/javascript" src="{% static 'js/login.js' %}"></script>
</body>
</html>
登陆界面js文件:static/login.js
// 登陆界面js文件:static/login.js
let vm = new Vue({
el: '#app',
// 修改Vue变量的读取语法
delimiters: ['[[', ']]'],
data: {
username: '',
password: '',
error_username: false,
error_password: false,
remembered: false,
},
methods: {
// 检查账号
check_username(){
let re = /^[a-zA-Z0-9_-]{5,20}$/;
if (re.test(this.username)) {
this.error_username = false;
} else {
this.error_username = true;
}
},
// 检查密码
check_password(){
let re = /^[0-9A-Za-z]{8,20}$/;
if (re.test(this.password)) {
this.error_password = false;
} else {
this.error_password = true;
}
},
// 表单提交
on_submit(){
this.check_username();
this.check_password();
if (this.error_username == true || this.error_password == true) {
// 不满足登录条件:禁用表单
window.event.returnValue = false
}
},
// qq登录
qq_login(){
let next = get_query_string('next') || '/';
let url = '/qq/login/?next=' + next;
axios.get(url, {
responseType: 'json'
})
.then(response => {
location.href = response.data.login_url;
})
.catch(error => {
console.log(error.response);
})
}
}
});
多账号登录
- Django自带的用户认证后端默认是使用用户名实现用户认证的。
- 用户认证后端位置:
django.contrib.auth.backends.ModelBackend。 - 如果想实现用户名和手机号都可以认证用户,就需要自定义用户认证后端。
- 自定义用户认证后端步骤
• 在users应用中新建utils.py文件
• 新建类,继承自ModelBackend
• 重写认证authenticate()方法
• 分别使用用户名和手机号查询用户
• 返回查询到的用户实例
自定义用户认证后端
Django自带认证后端源码

dev.py 开发环境的配置文件,重构authenticate方法
# AUTHENTICATION_BACKENDS = ['django.contrib.auth.backends.ModelBackend'] 源码中的authenticate方法的路径,用于验证登录用户名和手机号
AUTHENTICATION_BACKENDS = ['users.utils.UsernameMobileBackend'] # 自己重构的authenticate方法的路径
重写authenticate方法用于验证手机登录和用户名登录文件:apps/users/utils.py
# -*- encoding: utf-8 -*-
"""
@File : utils.py
@Time : 2020/8/11 9:42
@Author : chen
重写authenticate方法用于验证手机登录和用户名登录文件:apps/users/utils.py
"""
from django.contrib.auth.backends import ModelBackend # authenticate方法外的类
import re # 正则表达式
from users.models import User
def get_user_by_account(account):
"""
获取user对象
:param account: 用户名或者手机号
:return: user对象
"""
try:
if re.match(r'^1[3-9]\d{9}', account):
user = User.objects.get(mobile=account)
else:
user = User.objects.get(username=account)
# except User.DoesNotExist:
except:
return None
# 没有异常发生的时候
else:
return user
class UsernameMobileBackend(ModelBackend):
"""自定义用户认证手机号,用户名登录后端"""
def authenticate(self, request, username=None, password=None, **kwargs):
"""
重写认证方法
:param username: 用户名或者手机号
:param password: 密码明文
:param kwargs: 额外参数
:return: user
"""
user = get_user_by_account(username)
if user and user.check_password(password):
return user
else:
return None
2、首页用户名展示
首页用户名展示方案
方案一
- 模板中 request 变量直接渲染用户名
- 缺点:不方便做首页静态化
{# 登录用户的名称显示 #}
{% if user.is_authenticated %}
<div class="login_btn fl">
欢迎您:<em>{{ user.username }}</em>
<span>|</span>
<a href="#">退出</a>
</div>
{% else %} {# 用户未登录,显示为 #}
<div class="login_btn fl">
<a href="login.html">登录</a>
<span>|</span>
<a href="register.html">注册</a>
</div>
{% endif %}
方案二
- 发送ajax请求获取用户信息
- 缺点:需要发送网络请求
<div class="login_btn fl">
{# ajax渲染 #}
</div>
方案三
- Vue读取cookie渲染用户信息
首页界面:templates/index.html
{#首页界面:templates/index.html #}
{% load static %}
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html;charset=UTF-8">
<title>LG商城-首页</title>
<link rel="stylesheet" type="text/css" href="{% static 'css/reset.css' %}">
<link rel="stylesheet" type="text/css" href="{% static 'css/main.css' %}">
<script type="text/javascript" src="{% static 'js/jquery-1.12.4.min.js' %}"></script>
<script type="text/javascript" src="{% static 'js/vue-2.5.16.js' %}"></script>
<script type="text/javascript" src="{% static 'js/axios-0.18.0.min.js' %}"></script>
</head>
<body>
<div id="app">
<div class="header_con" v-cloak> {# v-cloak加载显示的问题 #}
<div class="header">
<div class="welcome fl">欢迎来到LG商城!</div>
<div class="fr">
{# 方法一 登录用户的名称显示 #}
{# {% if user.is_authenticated %}#}
{# <div class="login_btn fl">#}
{# 欢迎您:<em>{{ user.username }}</em>#}
{# <span>|</span>#}
{# <a href="#">退出</a>#}
{# </div>#}
{# {% else %} {# 用户未登录,显示为 #}
{# <div class="login_btn fl">#}
{# <a href="login.html">登录</a>#}
{# <span>|</span>#}
{# <a href="register.html">注册</a>#}
{# </div>#}
{# {% endif %}#}
{# 方法三: Vue读取cookie渲染用户信息 v-if="username"有值就显示 #}
<div v-if="username" class="login_btn fl">
欢迎您:<em>[[ username ]]</em>
<span>|</span>
<a href="#">退出</a>
</div>
{# v-else #}
<div v-else class="login_btn fl">
<a href="login.html">登录</a>
<span>|</span>
<a href="register.html">注册</a>
</div>
<div class="user_link fl">
<span>|</span>
<a href="user_center_info.html">用户中心</a>
<span>|</span>
<a href="cart.html">我的购物车</a>
<span>|</span>
<a href="user_center_order.html">我的订单</a>
</div>
</div>
</div>
</div>
<div class="search_bar clearfix">
<a href="index.html" class="logo fl"><img src="{% static 'images/1.png' %}"></a>
<div class="search_wrap fl">
<form method="get" action="/search/" class="search_con">
<input type="text" class="input_text fl" name="q" placeholder="搜索商品">
<input type="submit" class="input_btn fr" name="" value="搜索">
</form>
<ul class="search_suggest fl">
<li><a href="#">索尼微单</a></li>
<li><a href="#">优惠15元</a></li>
<li><a href="#">美妆个护</a></li>
<li><a href="#">买2免1</a></li>
</ul>
</div>
<div class="guest_cart fr">
<a href="cart.html" class="cart_name fl">我的购物车</a>
<div class="goods_count fl" id="show_count">2</div>
<ul class="cart_goods_show">
<li>
<img src="../static/images/goods/goods001.jpg" alt="商品图片">
<h4>华为 HUAWEI P10 Plus 6GB+64GB 钻雕金 移动联通电信4G手机 双卡双待</h4>
<div>1</div>
</li>
<li>
<img src="../static/images/goods/goods002.jpg" alt="商品图片">
<h4>Apple iPhoneX 64GB 深空灰色 移动联通电信4G手机</h4>
<div>1</div>
</li>
</ul>
</div>
</div>
<div class="navbar_con">
<div class="navbar">
<h1 class="fl">商品分类</h1>
<ul class="sub_menu">
<li>
<div class="level1">
<a href="http://shouji.jd.com/">手机</a><a href="#">运营商</a><a href="#">数码</a>
</div>
<div class="level2">
<div class="list_group">
<div class="group_name fl">手机通讯 ></div>
<div class="group_detail fl">
<a href="list.html">手机</a>
<a href="#">对讲机</a>
<a href="#">以旧换新</a>
<a href="#">手机维修</a>
</div>
</div>
<div class="list_group">
<div class="group_name fl">运营商 ></div>
<div class="group_detail fl">
<a href="#">合约机</a>
<a href="#">选号码</a>
<a href="#">固话宽带</a>
<a href="#">办套餐</a>
<a href="#">充话费/流量</a>
<a href="#">中国电信</a>
<a href="#">中国移动</a>
<a href="#">中国联通</a>
<a href="#">京东通信</a>
<a href="#">170选号</a>
</div>
</div>
</div>
</li>
<li>
<div class="level1">
<a href="#">电脑</a><a href="#">办公</a>
</div>
<div class="level2">
<div class="list_group">
<div class="group_name fl">电脑 ></div>
<div class="group_detail fl">
<a href="#">曲面电视</a>
<a href="#">超薄电视</a>
<a href="#">HDR电视</a>
<a href="#">OLED电视</a>
<a href="#">4K超清电视</a>
<a href="#">人工智能电视</a>
<a href="#">55英寸</a>
<a href="#">65英寸</a>
</div>
</div>
</div>
</li>
<li>
<div class="level1">
<a href="#">家居</a><a href="#">家具</a><a href="#">家装</a><a href="#">厨具</a>
</div>
<div class="level2">
<div class="list_group">
<div class="group_name fl">家具 ></div>
<div class="group_detail fl">
<a href="#">曲面电视</a>
<a href="#">超薄电视</a>
<a href="#">HDR电视</a>
<a href="#">OLED电视</a>
<a href="#">4K超清电视</a>
<a href="#">人工智能电视</a>
<a href="#">55英寸</a>
<a href="#">65英寸</a>
</div>
</div>
</div>
</li>
<li>
<div class="level1">
<a href="#">男装</a><a href="#">女装</a><a href="#">童装</a><a href="#">内衣</a>
</div>
<div class="level2">
<div class="list_group">
<div class="group_name fl">男装 ></div>
<div class="group_detail fl">
<a href="#">男装</a>
</div>
</div>
</div>
</li>
<li>
<div class="level1">
<a href="#">女鞋</a><a href="#">箱包</a><a href="#">钟表</a><a href="#">珠宝</a>
</div>
<div class="level2">
<div class="list_group">
<div class="group_name fl">女鞋 ></div>
<div class="group_detail fl">
<a href="#">女鞋</a>
</div>
</div>
</div>
</li>
<li>
<div class="level1">
<a href="#">男鞋</a><a href="#">运动</a><a href="#">户外</a>
</div>
<div class="level2">
<div class="list_group">
<div class="group_name fl">男鞋 ></div>
<div class="group_detail fl">
<a href="#">男鞋</a>
</div>
</div>
</div>
</li>
<li>
<div class="level1">
<a href="#">房产</a><a href="#">汽车</a><a href="#">汽车用品</a>
</div>
<div class="level2">
<div class="list_group">
<div class="group_name fl">汽车用品 ></div>
<div class="group_detail fl">
<a href="#">汽车用品</a>
</div>
</div>
</div>
</li>
<li>
<div class="level1">
<a href="#">母婴</a><a href="#">玩具乐器</a>
</div>
<div class="level2">
<div class="list_group">
<div class="group_name fl">玩具乐器 ></div>
<div class="group_detail fl">
<a href="#">玩具乐器</a>
</div>
</div>
</div>
</li>
<li>
<div class="level1">
<a href="#">食品</a><a href="#">酒类</a><a href="#">生鲜</a><a href="#">特产</a>
</div>
<div class="level2">
<div class="list_group">
<div class="group_name fl">食品 ></div>
<div class="group_detail fl">
<a href="#">食品</a>
</div>
</div>
</div>
</li>
<li>
<div class="level1">
<a href="#">图书</a><a href="#">音像</a><a href="#">电子书</a>
</div>
<div class="level2">
<div class="list_group">
<div class="group_name fl">图书 ></div>
<div class="group_detail fl">
<a href="#">图书</a>
</div>
</div>
</div>
</li>
<li>
<div class="level1">
<a href="#">机票</a><a href="#">酒店</a><a href="#">旅游</a><a href="#">生活</a>
</div>
<div class="level2">
<div class="list_group">
<div class="group_name fl">机票 ></div>
<div class="group_detail fl">
<a href="#">机票</a>
</div>
</div>
</div>
</li>
</ul>
<ul class="navlist fl">
<li><a href="">首页</a></li>
<li class="interval">|</li>
<li><a href="">真划算</a></li>
<li class="interval">|</li>
<li><a href="">抽奖</a></li>
</ul>
</div>
</div>
<div class="pos_center_con clearfix">
<ul class="slide">
<li><a href="#"><img src="../static/images/slide01.jpg" alt="幻灯片01"></a></li>
<li><a href="#"><img src="../static/images/slide02.jpg" alt="幻灯片02"></a></li>
<li><a href="#"><img src="../static/images/slide03.jpg" alt="幻灯片03"></a></li>
<li><a href="#"><img src="../static/images/slide04.jpg" alt="幻灯片04"></a></li>
</ul>
<div class="prev"></div>
<div class="next"></div>
<ul class="points"></ul>
<div class="news">
<div class="news_title">
<h3>快讯</h3>
<a href="#">更多 ></a>
</div>
<ul class="news_list">
<li><a href="#">i7顽石低至4199元</a></li>
<li><a href="#">奥克斯专场 正1匹空调1313元抢</a></li>
<li><a href="#">荣耀9青春版 高配 领券立减220元</a></li>
<li><a href="#">LG探索公益新模式</a></li>
<li><a href="#">i7顽石低至4199元</a></li>
<li><a href="#">正1匹空调1313元抢</a></li>
<li><a href="#">奥克斯专场 正1匹空调1313元抢</a></li>
</ul>
<a href="#" class="advs"><img src="../static/images/adv01.jpg"></a>
</div>
</div>
<div class="floor_adv" v-cloak>
<div class="list_model">
<div class="list_title clearfix">
<h3 class="fl" id="model01">1F 手机通讯</h3>
<div class="subtitle fr">
<a @mouseenter="f1_tab=1" :class="f1_tab===1?'active':''">时尚新品</a>
<a @mouseenter="f1_tab=2" :class="f1_tab===2?'active':''">畅想低价</a>
<a @mouseenter="f1_tab=3" :class="f1_tab===3?'active':''">手机配件</a>
</div>
</div>
<div class="goods_con clearfix">
<div class="goods_banner fl">
<img src="../static/images/banner01.jpg">
<div class="channel">
<a href="#">手机</a>
<a href="#">配件</a>
<a href="#">充值</a>
<a href="#">优惠券</a>
</div>
<div class="key_words">
<a href="#">荣耀手机</a>
<a href="#">国美手机</a>
<a href="#">华为手机</a>
<a href="#">热销推荐</a>
<a href="#">以旧换新</a>
<a href="#">潮3C</a>
<a href="#">全面屏</a>
<a href="#">守护宝</a>
<a href="#">存储卡</a>
<a href="#">保护套</a>
</div>
</div>
<div class="goods_list_con">
<ul v-show="f1_tab===1" class="goods_list fl">
<li>
<a href="http://itcast.cn/" class="goods_pic"><img src="../static/images/goods/goods003.jpg"></a>
<h4><a href="#" title="360手机 N6 Pro 全网通 6GB+128GB 极夜黑">360手机 N6 Pro 全网通 6GB+128GB 极夜黑</a></h4>
<div class="price">¥ 2699.00</div>
</li>
<li>
<a href="#" class="goods_pic"><img src="../static/images/goods/goods002.jpg"></a>
<h4><a href="#">iphoneX N6 Pro 全网通 6GB+128GB 极夜黑</a></h4>
<div class="price">¥ 7788.00</div>
</li>
<li>
<a href="#" class="goods_pic"><img src="../static/images/goods/goods001.jpg"></a>
<h4><a href="#">360手机 N6 Pro 全网通 6GB+128GB 极夜黑</a></h4>
<div class="price">¥ 1988.00</div>
</li>
<li>
<a href="#" class="goods_pic"><img src="../static/images/goods/goods004.jpg"></a>
<h4><a href="#">360手机 N6 Pro 全网通 6GB+128GB 极夜黑</a></h4>
<div class="price">¥ 3688.00</div>
</li>
<li>
<a href="#" class="goods_pic"><img src="../static/images/goods/goods005.jpg"></a>
<h4><a href="#">360手机 N6 Pro 全网通 6GB+128GB 极夜黑</a></h4>
<div class="price">¥ 4288.80</div>
</li>
<li>
<a href="#" class="goods_pic"><img src="../static/images/goods/goods003.jpg"></a>
<h4><a href="#">360手机 N6 Pro 全网通 6GB+128GB 极夜黑</a></h4>
<div class="price">¥ 2699.00</div>
</li>
<li>
<a href="#" class="goods_pic"><img src="../static/images/goods/goods002.jpg"></a>
<h4><a href="#">iphoneX N6 Pro 全网通 6GB+128GB 极夜黑</a></h4>
<div class="price">¥ 7788.00</div>
</li>
<li>
<a href="#" class="goods_pic"><img src="../static/images/goods/goods001.jpg"></a>
<h4><a href="#">360手机 N6 Pro 全网通 6GB+128GB 极夜黑</a></h4>
<div class="price">¥ 1988.00</div>
</li>
<li>
<a href="#" class="goods_pic"><img src="../static/images/goods/goods004.jpg"></a>
<h4><a href="#">360手机 N6 Pro 全网通 6GB+128GB 极夜黑</a></h4>
<div class="price">¥ 3688.00</div>
</li>
<li>
<a href="#" class="goods_pic"><img src="../static/images/goods/goods005.jpg"></a>
<h4><a href="#">360手机 N6 Pro 全网通 6GB+128GB 极夜黑</a></h4>
<div class="price">¥ 4288.80</div>
</li>
</ul>
<ul v-show="f1_tab===2" class="goods_list fl">
<li>
<a href="#" class="goods_pic"><img src="../static/images/goods/goods002.jpg"></a>
<h4><a href="#">iphoneX N6 Pro 全网通 6GB+128GB 极夜黑</a></h4>
<div class="price">¥ 7788.00</div>
</li>
<li>
<a href="#" class="goods_pic"><img src="../static/images/goods/goods001.jpg"></a>
<h4><a href="#">360手机 N6 Pro 全网通 6GB+128GB 极夜黑</a></h4>
<div class="price">¥ 1988.00</div>
</li>
<li>
<a href="#" class="goods_pic"><img src="../static/images/goods/goods004.jpg"></a>
<h4><a href="#">360手机 N6 Pro 全网通 6GB+128GB 极夜黑</a></h4>
<div class="price">¥ 3688.00</div>
</li>
<li>
<a href="#" class="goods_pic"><img src="../static/images/goods/goods005.jpg"></a>
<h4><a href="#">360手机 N6 Pro 全网通 6GB+128GB 极夜黑</a></h4>
<div class="price">¥ 4288.80</div>
</li>
<li>
<a href="#" class="goods_pic"><img src="../static/images/goods/goods003.jpg"></a>
<h4><a href="#" title="360手机 N6 Pro 全网通 6GB+128GB 极夜黑">360手机 N6 Pro 全网通 6GB+128GB 极夜黑</a></h4>
<div class="price">¥ 2699.00</div>
</li>
<li>
<a href="#" class="goods_pic"><img src="../static/images/goods/goods002.jpg"></a>
<h4><a href="#">iphoneX N6 Pro 全网通 6GB+128GB 极夜黑</a></h4>
<div class="price">¥ 7788.00</div>
</li>
<li>
<a href="#" class="goods_pic"><img src="../static/images/goods/goods001.jpg"></a>
<h4><a href="#">360手机 N6 Pro 全网通 6GB+128GB 极夜黑</a></h4>
<div class="price">¥ 1988.00</div>
</li>
<li>
<a href="#" class="goods_pic"><img src="../static/images/goods/goods004.jpg"></a>
<h4><a href="#">360手机 N6 Pro 全网通 6GB+128GB 极夜黑</a></h4>
<div class="price">¥ 3688.00</div>
</li>
<li>
<a href="#" class="goods_pic"><img src="../static/images/goods/goods005.jpg"></a>
<h4><a href="#">360手机 N6 Pro 全网通 6GB+128GB 极夜黑</a></h4>
<div class="price">¥ 4288.80</div>
</li>
<li>
<a href="#" class="goods_pic"><img src="../static/images/goods/goods003.jpg"></a>
<h4><a href="#">360手机 N6 Pro 全网通 6GB+128GB 极夜黑</a></h4>
<div class="price">¥ 2699.00</div>
</li>
</ul>
<ul v-show="f1_tab===3" class="goods_list fl">
<li>
<a href="#" class="goods_pic"><img src="../static/images/goods/goods002.jpg"></a>
<h4><a href="#">iphoneX N6 Pro 全网通 6GB+128GB 极夜黑</a></h4>
<div class="price">¥ 7788.00</div>
</li>
<li>
<a href="#" class="goods_pic"><img src="../static/images/goods/goods001.jpg"></a>
<h4><a href="#">360手机 N6 Pro 全网通 6GB+128GB 极夜黑</a></h4>
<div class="price">¥ 1988.00</div>
</li>
<li>
<a href="#" class="goods_pic"><img src="../static/images/goods/goods004.jpg"></a>
<h4><a href="#">360手机 N6 Pro 全网通 6GB+128GB 极夜黑</a></h4>
<div class="price">¥ 3688.00</div>
</li>
<li>
<a href="#" class="goods_pic"><img src="../static/images/goods/goods005.jpg"></a>
<h4><a href="#">360手机 N6 Pro 全网通 6GB+128GB 极夜黑</a></h4>
<div class="price">¥ 4288.80</div>
</li>
<li>
<a href="#" class="goods_pic"><img src="../static/images/goods/goods003.jpg"></a>
<h4><a href="#">360手机 N6 Pro 全网通 6GB+128GB 极夜黑</a></h4>
<div class="price">¥ 2699.00</div>
</li>
<li>
<a href="#" class="goods_pic"><img src="../static/images/goods/goods003.jpg"></a>
<h4><a href="#" title="360手机 N6 Pro 全网通 6GB+128GB 极夜黑">360手机 N6 Pro 全网通 6GB+128GB 极夜黑</a></h4>
<div class="price">¥ 2699.00</div>
</li>
<li>
<a href="#" class="goods_pic"><img src="../static/images/goods/goods002.jpg"></a>
<h4><a href="#">iphoneX N6 Pro 全网通 6GB+128GB 极夜黑</a></h4>
<div class="price">¥ 7788.00</div>
</li>
<li>
<a href="#" class="goods_pic"><img src="../static/images/goods/goods001.jpg"></a>
<h4><a href="#">360手机 N6 Pro 全网通 6GB+128GB 极夜黑</a></h4>
<div class="price">¥ 1988.00</div>
</li>
<li>
<a href="#" class="goods_pic"><img src="../static/images/goods/goods004.jpg"></a>
<h4><a href="#">360手机 N6 Pro 全网通 6GB+128GB 极夜黑</a></h4>
<div class="price">¥ 3688.00</div>
</li>
<li>
<a href="#" class="goods_pic"><img src="../static/images/goods/goods005.jpg"></a>
<h4><a href="#">360手机 N6 Pro 全网通 6GB+128GB 极夜黑</a></h4>
<div class="price">¥ 4288.80</div>
</li>
</ul>
</div>
</div>
</div>
<div class="list_model model02">
<div class="list_title clearfix">
<h3 class="fl" id="model01">2F 电脑数码</h3>
<div class="subtitle fr">
<a @mouseenter="f2_tab=1" :class="f2_tab===1?'active':''">加价换购</a>
<a @mouseenter="f2_tab=2" :class="f2_tab===2?'active':''">畅享低价</a>
</div>
</div>
<div class="goods_con clearfix">
<div class="goods_banner fl">
<img src="../static/images/banner02.jpg">
<div class="channel">
<a href="#">电脑</a>
<a href="#">数码</a>
<a href="#">配件</a>
<a href="#">潮电子</a>
</div>
<div class="key_words">
<a href="#">Apple</a>
<a href="#">神舟战神</a>
<a href="#">单反相机</a>
<a href="#">智能家居</a>
<a href="#">智能路由</a>
<a href="#">限时抢</a>
<a href="#">顽石</a>
<a href="#">微单</a>
<a href="#">耳机</a>
<a href="#">投影机</a>
</div>
</div>
<div class="goods_list_con">
<ul v-show="f2_tab===1" class="goods_list fl">
<li>
<a href="#" class="goods_pic"><img src="../static/images/goods/goods008.jpg"></a>
<h4><a href="#" title="华硕明星爆款 八代i7顽石低至4199">华硕明星爆款 八代i7顽石低至4199</a></h4>
<div class="price">¥ 4199.00</div>
</li>
<li>
<a href="#" class="goods_pic"><img src="../static/images/goods/goods002.jpg"></a>
<h4><a href="#">iphoneX N6 Pro 全网通 6GB+128GB 极夜黑</a></h4>
<div class="price">¥ 7788.00</div>
</li>
<li>
<a href="#" class="goods_pic"><img src="../static/images/goods/goods001.jpg"></a>
<h4><a href="#">360手机 N6 Pro 全网通 6GB+128GB 极夜黑</a></h4>
<div class="price">¥ 1988.00</div>
</li>
<li>
<a href="#" class="goods_pic"><img src="../static/images/goods/goods004.jpg"></a>
<h4><a href="#">360手机 N6 Pro 全网通 6GB+128GB 极夜黑</a></h4>
<div class="price">¥ 3688.00</div>
</li>
<li>
<a href="#" class="goods_pic"><img src="../static/images/goods/goods005.jpg"></a>
<h4><a href="#">360手机 N6 Pro 全网通 6GB+128GB 极夜黑</a></h4>
<div class="price">¥ 4288.80</div>
</li>
<li>
<a href="#" class="goods_pic"><img src="../static/images/goods/goods003.jpg"></a>
<h4><a href="#">360手机 N6 Pro 全网通 6GB+128GB 极夜黑</a></h4>
<div class="price">¥ 2699.00</div>
</li>
<li>
<a href="#" class="goods_pic"><img src="../static/images/goods/goods002.jpg"></a>
<h4><a href="#">iphoneX N6 Pro 全网通 6GB+128GB 极夜黑</a></h4>
<div class="price">¥ 7788.00</div>
</li>
<li>
<a href="#" class="goods_pic"><img src="../static/images/goods/goods001.jpg"></a>
<h4><a href="#">360手机 N6 Pro 全网通 6GB+128GB 极夜黑</a></h4>
<div class="price">¥ 1988.00</div>
</li>
<li>
<a href="#" class="goods_pic"><img src="../static/images/goods/goods004.jpg"></a>
<h4><a href="#">360手机 N6 Pro 全网通 6GB+128GB 极夜黑</a></h4>
<div class="price">¥ 3688.00</div>
</li>
<li>
<a href="#" class="goods_pic"><img src="../static/images/goods/goods005.jpg"></a>
<h4><a href="#">360手机 N6 Pro 全网通 6GB+128GB 极夜黑</a></h4>
<div class="price">¥ 4288.80</div>
</li>
</ul>
<ul v-show="f2_tab===2" class="goods_list fl">
<li>
<a href="#" class="goods_pic"><img src="../static/images/goods/goods002.jpg"></a>
<h4><a href="#">iphoneX N6 Pro 全网通 6GB+128GB 极夜黑</a></h4>
<div class="price">¥ 7788.00</div>
</li>
<li>
<a href="#" class="goods_pic"><img src="../static/images/goods/goods008.jpg"></a>
<h4><a href="#" title="华硕明星爆款 八代i7顽石低至4199">华硕明星爆款 八代i7顽石低至4199</a></h4>
<div class="price">¥ 4199.00</div>
</li>
<li>
<a href="#" class="goods_pic"><img src="../static/images/goods/goods004.jpg"></a>
<h4><a href="#">360手机 N6 Pro 全网通 6GB+128GB 极夜黑</a></h4>
<div class="price">¥ 3688.00</div>
</li>
<li>
<a href="#" class="goods_pic"><img src="../static/images/goods/goods001.jpg"></a>
<h4><a href="#">360手机 N6 Pro 全网通 6GB+128GB 极夜黑</a></h4>
<div class="price">¥ 1988.00</div>
</li>
<li>
<a href="#" class="goods_pic"><img src="../static/images/goods/goods005.jpg"></a>
<h4><a href="#">360手机 N6 Pro 全网通 6GB+128GB 极夜黑</a></h4>
<div class="price">¥ 4288.80</div>
</li>
<li>
<a href="#" class="goods_pic"><img src="../static/images/goods/goods003.jpg"></a>
<h4><a href="#">360手机 N6 Pro 全网通 6GB+128GB 极夜黑</a></h4>
<div class="price">¥ 2699.00</div>
</li>
<li>
<a href="#" class="goods_pic"><img src="../static/images/goods/goods001.jpg"></a>
<h4><a href="#">360手机 N6 Pro 全网通 6GB+128GB 极夜黑</a></h4>
<div class="price">¥ 1988.00</div>
</li>
<li>
<a href="#" class="goods_pic"><img src="../static/images/goods/goods004.jpg"></a>
<h4><a href="#">360手机 N6 Pro 全网通 6GB+128GB 极夜黑</a></h4>
<div class="price">¥ 3688.00</div>
</li>
<li>
<a href="#" class="goods_pic"><img src="../static/images/goods/goods002.jpg"></a>
<h4><a href="#">iphoneX N6 Pro 全网通 6GB+128GB 极夜黑</a></h4>
<div class="price">¥ 7788.00</div>
</li>
<li>
<a href="#" class="goods_pic"><img src="../static/images/goods/goods005.jpg"></a>
<h4><a href="#">360手机 N6 Pro 全网通 6GB+128GB 极夜黑</a></h4>
<div class="price">¥ 4288.80</div>
</li>
</ul>
</div>
</div>
</div>
<div class="list_model model03">
<div class="list_title clearfix">
<h3 class="fl" id="model01">3F 家居家装</h3>
<div class="subtitle fr">
<a @mouseenter="f3_tab=1" :class="f3_tab===1?'active':''">生活用品</a>
<a @mouseenter="f3_tab=2" :class="f3_tab===2?'active':''">厨房用品</a>
</div>
</div>
<div class="goods_con clearfix">
<div class="goods_banner fl">
<img src="../static/images/banner03.jpg">
<div class="channel">
<a href="#">家居日用</a>
<a href="#">家纺寝居</a>
<a href="#">住宅家具</a>
</div>
<div class="key_words">
<a href="#">厨具餐饮</a>
<a href="#">被子</a>
<a href="#">实木床</a>
<a href="#">箭牌马桶</a>
<a href="#">指纹锁</a>
<a href="#">电饭煲</a>
<a href="#">热水器</a>
<a href="#">席梦思</a>
<a href="#">沙发</a>
<a href="#">酒柜</a>
</div>
</div>
<div class="goods_list_con">
<ul v-show="f3_tab===1" class="goods_list fl">
<li>
<a href="#" class="goods_pic"><img src="../static/images/goods/goods009.jpg"></a>
<h4><a href="#" title="维达3层超韧120抽软抽纸每提4包【大规格L】V2240(4包)">维达3层超韧120抽软抽纸每提4包【大规格L】V2240(4包)</a></h4>
<div class="price">¥ 18.80</div>
</li>
<li>
<a href="#" class="goods_pic"><img src="../static/images/goods/goods002.jpg"></a>
<h4><a href="#">iphoneX N6 Pro 全网通 6GB+128GB 极夜黑</a></h4>
<div class="price">¥ 7788.00</div>
</li>
<li>
<a href="#" class="goods_pic"><img src="../static/images/goods/goods001.jpg"></a>
<h4><a href="#">360手机 N6 Pro 全网通 6GB+128GB 极夜黑</a></h4>
<div class="price">¥ 1988.00</div>
</li>
<li>
<a href="#" class="goods_pic"><img src="../static/images/goods/goods004.jpg"></a>
<h4><a href="#">360手机 N6 Pro 全网通 6GB+128GB 极夜黑</a></h4>
<div class="price">¥ 3688.00</div>
</li>
<li>
<a href="#" class="goods_pic"><img src="../static/images/goods/goods005.jpg"></a>
<h4><a href="#">360手机 N6 Pro 全网通 6GB+128GB 极夜黑</a></h4>
<div class="price">¥ 4288.80</div>
</li>
<li>
<a href="#" class="goods_pic"><img src="../static/images/goods/goods003.jpg"></a>
<h4><a href="#">360手机 N6 Pro 全网通 6GB+128GB 极夜黑</a></h4>
<div class="price">¥ 2699.00</div>
</li>
<li>
<a href="#" class="goods_pic"><img src="../static/images/goods/goods002.jpg"></a>
<h4><a href="#">iphoneX N6 Pro 全网通 6GB+128GB 极夜黑</a></h4>
<div class="price">¥ 7788.00</div>
</li>
<li>
<a href="#" class="goods_pic"><img src="../static/images/goods/goods001.jpg"></a>
<h4><a href="#">360手机 N6 Pro 全网通 6GB+128GB 极夜黑</a></h4>
<div class="price">¥ 1988.00</div>
</li>
<li>
<a href="#" class="goods_pic"><img src="../static/images/goods/goods004.jpg"></a>
<h4><a href="#">360手机 N6 Pro 全网通 6GB+128GB 极夜黑</a></h4>
<div class="price">¥ 3688.00</div>
</li>
<li>
<a href="#" class="goods_pic"><img src="../static/images/goods/goods005.jpg"></a>
<h4><a href="#">360手机 N6 Pro 全网通 6GB+128GB 极夜黑</a></h4>
<div class="price">¥ 4288.80</div>
</li>
</ul>
<ul v-show="f3_tab===2" class="goods_list fl">
<li>
<a href="#" class="goods_pic"><img src="../static/images/goods/goods002.jpg"></a>
<h4><a href="#">iphoneX N6 Pro 全网通 6GB+128GB 极夜黑</a></h4>
<div class="price">¥ 7788.00</div>
</li>
<li>
<a href="#" class="goods_pic"><img src="../static/images/goods/goods001.jpg"></a>
<h4><a href="#">360手机 N6 Pro 全网通 6GB+128GB 极夜黑</a></h4>
<div class="price">¥ 1988.00</div>
</li>
<li>
<a href="#" class="goods_pic"><img src="../static/images/goods/goods009.jpg"></a>
<h4><a href="#" title="维达3层超韧120抽软抽纸每提4包【大规格L】V2240(4包)">维达3层超韧120抽软抽纸每提4包【大规格L】V2240(4包)</a></h4>
<div class="price">¥ 18.80</div>
</li>
<li>
<a href="#" class="goods_pic"><img src="../static/images/goods/goods004.jpg"></a>
<h4><a href="#">360手机 N6 Pro 全网通 6GB+128GB 极夜黑</a></h4>
<div class="price">¥ 3688.00</div>
</li>
<li>
<a href="#" class="goods_pic"><img src="../static/images/goods/goods003.jpg"></a>
<h4><a href="#">360手机 N6 Pro 全网通 6GB+128GB 极夜黑</a></h4>
<div class="price">¥ 2699.00</div>
</li>
<li>
<a href="#" class="goods_pic"><img src="../static/images/goods/goods005.jpg"></a>
<h4><a href="#">360手机 N6 Pro 全网通 6GB+128GB 极夜黑</a></h4>
<div class="price">¥ 4288.80</div>
</li>
<li>
<a href="#" class="goods_pic"><img src="../static/images/goods/goods002.jpg"></a>
<h4><a href="#">iphoneX N6 Pro 全网通 6GB+128GB 极夜黑</a></h4>
<div class="price">¥ 7788.00</div>
</li>
<li>
<a href="#" class="goods_pic"><img src="../static/images/goods/goods001.jpg"></a>
<h4><a href="#">360手机 N6 Pro 全网通 6GB+128GB 极夜黑</a></h4>
<div class="price">¥ 1988.00</div>
</li>
<li>
<a href="#" class="goods_pic"><img src="../static/images/goods/goods005.jpg"></a>
<h4><a href="#">360手机 N6 Pro 全网通 6GB+128GB 极夜黑</a></h4>
<div class="price">¥ 4288.80</div>
</li>
<li>
<a href="#" class="goods_pic"><img src="../static/images/goods/goods004.jpg"></a>
<h4><a href="#">360手机 N6 Pro 全网通 6GB+128GB 极夜黑</a></h4>
<div class="price">¥ 3688.00</div>
</li>
</ul>
</div>
</div>
</div>
</div>
<div class="footer">
<div class="foot_link">
<a href="#">关于我们</a>
<span>|</span>
<a href="#">联系我们</a>
<span>|</span>
<a href="#">招聘人才</a>
<span>|</span>
<a href="#">友情链接</a>
</div>
<p>CopyRight © 2016 北京LG商业股份有限公司 All Rights Reserved</p>
<p>电话:010-****888 京ICP备*******8号</p>
</div>
</div>
<script type="text/javascript" src="{% static 'js/common.js' %}"></script>
<script type="text/javascript" src="{% static 'js/slide.js' %}"></script>
<script type="text/javascript" src="{% static 'js/index.js' %}"></script>
</body>
</html>
apps/users/views.py文件,用户后端验证视图文件
"""
视图文件
apps/users/views.py文件,用户后端验证视图文件
"""
from django.shortcuts import render, redirect, reverse
from django.http import HttpResponse, JsonResponse
from django.views import View
from .forms import RegisterForm, LoginForm
from .models import User
from django.contrib.auth import login, authenticate # authenticate封装的验证用户名和密码是否正确的方法
from django_redis import get_redis_connection
# 用户登陆
class LoginView(View):
"""用户名登陆"""
def get(self, request):
""" 提供登陆界面
:return: 登陆界面
"""
return render(request, 'login.html')
def post(self, request):
"""
实现登录逻辑
:param request: 请求对象
:return: 登录结果
"""
# 接受参数
login_form = LoginForm(request.POST)
# 校验参数
if login_form.is_valid():
# 接收参数
username = login_form.cleaned_data.get('username')
password = login_form.cleaned_data.get('password')
remembered = request.POST.get('remembered') # 没经过form验证,使用request接收参数
# 认证登录用户
# users = User.objects.get(username=username)
# users.check_password(password) # check_password验证密码封装的方法,返回值bool类型
""" authenticate方法源码
def authenticate(self, request, username=None, password=None, **kwargs):
if username is None:
username = kwargs.get(UserModel.USERNAME_FIELD)
try:
user = UserModel._default_manager.get_by_natural_key(username)
except UserModel.DoesNotExist:
# Run the default password hasher once to reduce the timing
# difference between an existing and a nonexistent user (#20760).
UserModel().set_password(password)
else:
if user.check_password(password) and self.user_can_authenticate(user):
return user
"""
user = authenticate(username=username, password=password) # 重构authenticate方法之后,可以验证手机号登录和用户名登录
if user is None:
# 用户名或者密码输入错误
return render(request, 'login.html', {"errmsg": "用户名或者密码输入错误"})
# 实现状态保持
login(request, user)
# 设置状态保持的周期
if remembered != 'on':
# 没选中记住密码,浏览器关闭就需要销毁session信息
request.session.set_expiry(0) # set_expiry过期时间
else:
# 选中记住密码,session信息默认保存两周
# request.session.set_expiry(60*60*24*14)
request.session.set_expiry(None)
# 后端将用户信息存入cookie
result = redirect(reverse('contents:index')) # redirect方法源码中会返回一个redirect_class
# set_cookie('key', 'value', 'erpriy') erpriy过期时间
result.set_cookie('username', user.username, max_age=3600*24*14) # 保存两周
# 响应登录结果 跳转到首页
return result
else:
print(login_form.errors.get_json_data())
context = {
"form_errors": login_form.errors,
}
return render(request, 'login.html', context=context)
class RegisterView(View):
"""用户注册"""
def get(self, request):
"""提供用户的注册界面"""
return render(request, 'register.html')
def post(self, request):
"""提供用户的注册逻辑"""
# 前端用户提交数据
form = RegisterForm(request.POST)
if form.is_valid():
# 接收参数
username = form.cleaned_data.get('username')
password = form.cleaned_data.get('password')
mobile = form.cleaned_data.get('mobile')
sms_code_client = request.POST.get('sms_code') # 验证短信验证码 sms_code是register.html 文件中命名的
# 判断用户输入的短信验证码是否正确
redis_conn = get_redis_connection('verify_code') # 链接redis中配置的数据库
sms_code_server = redis_conn.get('sms_%s' % mobile) # 根据存储时候的格式写
if sms_code_server is None:
return render(request, 'register.html', {'sms_code_errmsg': '短信验证码已经失效'}) # 错误信息渲染到前端界面
if sms_code_server.decode() != sms_code_client: # sms_code_server数据类型需要转换
return render(request, 'register.html', {'sms_code_errmsg': '短信验证码填写错误'})
try:
# user = User(username=username, password=password, mobile=mobile)
# 下面的添加数据的方法是封装了加密等功能的函数,更安全
users = User.objects.create_user(username=username, password=password, mobile=mobile)
except: # 如果保存数据失败
return render(request, 'register.html', {'register_error_message': '注册失败'})
# 保持用户登录的状态
login(request, users)
# 返回响应
# return HttpResponse('success')
return redirect(reverse('contents:index')) # 注册成功,跳转到首页
else:
print(form.errors.get_json_data())
# return HttpResponse("fail")
# 返回注册错误信息到前端界面
context = {
'form_error': form.errors,
}
return render(request, 'register.html', context=context)
class UsernameExists(View):
""" 判断用户名是否已经存在"""
def get(self, request, username): # username用户名
count = User.objects.filter(username=username).count() # 查询数据库中信息
return JsonResponse({"code": 0, "errmsg": "OK", "count": count}) # 返回给前端界面
首页界面静态文件:static/js/index.js
// 首页界面静态文件:static/js/index.js
let vm = new Vue({
el: '#app', // 绑定app
delimiters: ['[[', ']]'], // 修改模板语法
data: {
username: getCookie('username'), // getCookie方法在common.js文件中定义
f1_tab: 1, // 1F 标签页控制
f2_tab: 1, // 2F 标签页控制
f3_tab: 1, // 3F 标签页控制
// 渲染首页购物车数据
cart_total_count: 0,
carts: [],
},
methods: {
// 获取简单购物车数据
get_carts(){
let url = '/carts/simple/';
axios.get(url, {
responseType: 'json',
})
.then(response => {
this.carts = response.data.cart_skus;
this.cart_total_count = 0;
for(let i=0;i<this.carts.length;i++){
if (this.carts[i].name.length>25){
this.carts[i].name = this.carts[i].name.substring(0, 25) + '...';
}
this.cart_total_count += this.carts[i].count;
}
})
.catch(error => {
console.log(error.response);
})
}
}
});
定义生成uuid的方法,获取cookie的方法文件:static/js/common.js
// 定义生成uuid的方法,获取cookie的方法文件:static/js/common.js文件
// 获取cookie
function getCookie(name) {
let r = document.cookie.match("\\b" + name + "=([^;]*)\\b");
return r ? r[1] : undefined;
}
// 提取地址栏中的查询字符串
function get_query_string(name) {
let reg = new RegExp('(^|&)' + name + '=([^&]*)(&|$)', 'i');
let r = window.location.search.substr(1).match(reg);
if (r != null) {
return decodeURI(r[2]);
}
return null;
}
// 生成uuid
function generateUUID() {
let d = new Date().getTime();
if(window.performance && typeof window.performance.now === "function"){
d += performance.now(); //use high-precision timer if available
}
let uuid = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
let r = (d + Math.random()*16)%16 | 0;
d = Math.floor(d/16);
return (c=='x' ? r : (r&0x3|0x8)).toString(16);
});
return uuid;
}
3、项目阶段总结

775

被折叠的 条评论
为什么被折叠?



