第一步:未登录时,访问需要用户认证的页面时,需要跳转到登录页,在dev.py中配置
python
# 当用户未登录而访问需要身份验证的页面时,将重定向到这个地址
LOGIN_URL = '/login'
第二步:登录后的重定向,如果刚才未登录的情况下,要访问用户中心页面,会直接跳转到登录页面,此时输入用户名密码之后会直接跳转到用户中心页面。
python
class LoginView(View):
def get(self, request):
return render(request, 'login.html')
def post(self, request):
username = request.POST.get('username')
password = request.POST.get('password')
remembered = request.POST.get('remembered')
if not all([username, password]):
return HttpResponseForbidden('缺少必须参数')
if not re.match(r'^[a-zA-Z0-9_-]{5,20}$', username):
return HttpResponseForbidden('请输入正确的用户名')
if not re.match(r'^[a-zA-Z0-9]{8,20}$', password):
return HttpResponseForbidden('密码8-20位')
user = authenticate(username=username, password=password)
if user is None:
return render(request, 'login.html', {'account_errmsg': '账号或密码错误'})
login(request, user)
print(request.session.session_key)
if remembered != 'on':
request.session.set_expiry(0)
else:
request.session.set_expiry(None) # 2周过期
# 在Django中,request.GET.get('next')的值是一个字符串,它代表用户在登录前尝试访问的原始URL。
# 这个值由Django自动添加到登录URL中,用于在用户成功登录后将其重定向回原始页面。
next = request.GET.get('next')
print(next)
if next:
# 重定向到next
response = redirect(next)
else:
# 重定向到首页
response = redirect(reverse('contents:index'))
# 新增设置cookie
response.set_cookie('username', user.username, max_age=3600 * 24 * 14)
return response
第三步:创建用户中心视图类
python
class UserInfoView(LoginRequiredMixin, View):
"""用户中心"""
def get(self, request):
context = {
'username': request.user.username,
'mobile': request.user.mobile,
'email': request.user.email,
'email_active': request.user.email_active,
}
return render(request, 'user_center_info.html', context=context)
第四步:User模型中增加邮箱字段
python
class User(AbstractUser):
mobile = models.CharField(max_length=11, unique=True, verbose_name='手机号')
email_active = models.BooleanField(default=False, verbose_name='邮箱验证状态')
def __str__(self):
return self.mobile
class Meta:
db_table = 'tb_user'
verbose_name = '用户'
verbose_name_plural = verbose_name
第五步:用户中心页面user_center_info.html
html
<!--{#<!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>小鱼商城-用户中心</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 id="app">
<div class="header_con">
<div class="header" v-cloak>
<div class="welcome fl">欢迎来到小鱼商城!</div>
<div class="fr">
<div v-if="username" class="login_btn fl">
欢迎您:<em>[[ username ]]</em>
<span>|</span>
<a href="{{ url('users:logout') }}">退出</a>
</div>
<div v-else class="login_btn fl">
<a href="{{ url('users:login') }}">登录</a>
<span>|</span>
<a href="{{ url('users:register') }}">注册</a>
</div>
<div class="user_link fl">
<span>|</span>
<a href="{{ url('users:info') }}">用户中心</a>
<span>|</span>
<a href="#">我的购物车</a>
<span>|</span>
<a href="#">我的订单</a>
</div>
</div>
</div>
</div>
<div class="search_bar clearfix">
<a href="{{ url('contents:index') }}" class="logo fl"><img src="{{ static('images/logo.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>
<div class="main_con clearfix">
<div class="left_menu_con clearfix">
<h3>用户中心</h3>
<ul>
<li><a href="{{ url('users:info') }}" class="active">· 个人信息</a></li>
{# <li><a href="{{ url('users:address') }}">· 收货地址</a></li>#}
<li><a href="#">· 全部订单</a></li>
{# <li><a href="{{ url('users:resetpwd') }}">· 修改密码</a></li>#}
</ul>
</div>
<div class="right_content clearfix" v-cloak>
<div class="info_con clearfix">
<h3 class="common_title2">基本信息</h3>
<ul class="user_info_list">
<li><span>用户名:</span>[[ username ]]</li>
<li><span>联系方式:</span>[[ mobile ]]</li>
<li>
<span>Email:</span>
<div v-if="set_email">
<input v-model="email" @blur="check_email" type="email" name="email" class="email">
<input @click="save_email" type="button" name="" value="保 存">
<input @click="cancel_email" type="reset" name="" value="取 消">
<div v-show="error_email" class="error_email_tip">邮箱格式错误</div>
</div>
<div v-else>
<input v-model="email" type="email" name="email" class="email" readonly>
<div v-if="email_active">
已验证
</div>
<div v-else>
待验证<input @click="save_email" :disabled="send_email_btn_disabled" type="button"
:value="send_email_tip">
</div>
</div>
</li>
</ul>
</div>
<h3 class="common_title2">最近浏览</h3>
<div class="has_view_list" v-cloak>
<ul class="goods_type_list clearfix">
<li v-for="sku in histories">
<a :href="sku.url"><img :src="sku.default_image_url"></a>
<h4><a :href="sku.url">[[ sku.name ]]</a></h4>
<div class="operate">
<span class="price">¥[[ sku.price ]]</span>
<span class="unit">台</span>
<a href="javascript:;" class="add_goods" title="加入购物车"></a>
</div>
</li>
</ul>
</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 © 2024 北京小鱼商业股份有限公司 All Rights Reserved</p>
<p>电话:010-****888 京ICP备*******8号</p>
</div>
</div>
<script type="text/javascript">
let username = "{{ username }}";
let mobile = "{{ mobile }}";
let email = "{{ email }}";
let email_active = "{{ email_active }}";
</script>
<script type="text/javascript" src="{{ static('js/common.js') }}"></script>
<script type="text/javascript" src="{{ static('js/user_center_info.js') }}"></script>
</body>
</html>
第六步:配置路由
python
path('info/', views.UserInfoView.as_view(), name='info'),
第七步:index.html中把用户中心的注解去掉
html
<!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>小鱼商城-首页</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">
<div class="header">
<div class="welcome fl">欢迎来到小鱼商城!</div>
<div class="fr">
<div v-if="username" class="login_btn fl">
欢迎您:<em>[[ username ]]</em>
<span>|</span>
<a href="{{ url('users:logout') }}">退出</a>
</div>
<div v-else class="login_btn fl">
<a href="{{ url('users:login') }}">登录</a>
<span>|</span>
<a href="{{ url('users:register') }}">注册</a>
</div>
<div class="user_link fl">
<span>|</span>
<a href="{{ url('users:info') }}">用户中心</a>
{# <span>|</span>#}
{# <a href="cart.html">我的购物车</a>#}
{# <span>|</span>#}
{# <a href="user_center_order.html">我的订单</a>#}
</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 © 2024 北京小鱼商业股份有限公司 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>