第四步、用户中心
程序员文章站
2022-05-24 18:14:15
...
1、把之前的页面整合起来,减少代码的重复性,添加父模板,
base.html父模板
{#首页 登录 注册 #}
{% load static %}
<!DOCTYPE >
<html lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html;charset=UTF-8">
<title>{% block title %}天天生鲜-首页{% endblock %}</title>
<link rel="stylesheet" type="text/css" href="{% static 'css/reset.css' %}">
<link rel="stylesheet" type="text/css" href="{% static 'css/main.css' %}">
<link rel="shortcut icon" href="{% static 'images/favicon.ico' %}">
{% block topfiles %}
<script type="text/javascript" src="/static/js/jquery-1.12.4.min.js"></script>
<script type="text/javascript" src="/static/js/jquery-ui.min.js"></script>
<script type="text/javascript" src="/static/js/slide.js"></script>
{% endblock %}
</head>
<body>
{#网页顶部欢迎信息模块#}
{% block header_con %}
<div class="header_con">
<div class="header">
<div class="welcome fl">欢迎来到天天生鲜!</div>
<div class="fr">
{% if user.is_authenticated %}
<div class="login_btn fl">
欢迎您: <em>{{ user.username }}</em>
<span>|</span>
<a href="{% url 'user:logout' %}">退出</a>
</div>
{% else %}
<div class="login_btn fl">
<a href="{% url 'user:login' %}">登录</a>
<span>|</span>
<a href="{% url 'user:register' %}">注册</a>
</div>
{% endif %}
<div class="user_link fl">
<span>|</span>
<a href="{% url 'user:user' %}">用户中心</a>
<span>|</span>
<a href="{% url 'cart:show' %}">我的购物车</a>
<span>|</span>
<a href="{% url 'user:order' 1 %}">我的订单</a>
</div>
</div>
</div>
</div>
{% endblock %}
{#网页顶部搜索框#}
{% block search_bar %}
<div class="search_bar clearfix">
<a href="{% url 'goods:index' %}" class="logo fl"><img src="{% static 'images/logo.png' %}" alt=""></a>
<div class="search_con fl">
<form action="/search" method="get">
<input type="text" class="input_text fl" name="q" placeholder="搜索商品" value="">
<input type="submit" class="input_btn fr" name="" value="搜索">
</form>
</div>
<div class="guest_cart fr">
<a href="{% url 'cart:show' %}" class="cart_name fl">我的购物车</a>
<div class="goods_count fl" id="show_count">{{ cart_count }}</div>
</div>
</div>
{% endblock %}
{#网页主题内容块#}
{% block body %}
{% endblock %}
<div class="footer">
<div class="foot_link">
<a href="javascript:alert('待开发!');">关于我们</a>
<span>|</span>
<a href="javascript:alert('待开发!');">联系我们</a>
<span>|</span>
<a href="javascript:alert('待开发!');">招聘人才</a>
<span>|</span>
<a href="javascript:alert('待开发!');">友情链接</a>
</div>
<p>CopyRight © 2019 *************************</p>
<p>*********ivy***********</p>
</div>
{#网页底部div元素#}
{% block bottom %}{% endblock %}
{#网页底部文件#}
{% block bottomfiles %}{% endblock %}
</body>
</html>
base_no_cast.html模板页面
{#购物车 提交订单 #}
{% extends 'base.html' %}
{% load static %}
{#网页顶部搜索框#}
{% block search_bar %}
<div class="search_bar clearfix">
<a href="{% url 'goods:index' %}" class="logo fl"><img src="{% static 'images/logo.png' %}" alt=""></a>
<div class="sub_page_name fl">| {% block page_title %}{% endblock %}</div>
<div class="search_con fr">
<input type="text" class="input_text fl" name="" placeholder="搜索商品">
<input type="button" class="input_btn fr" name="" value="搜索">
</div>
</div>
{% endblock %}
base_user_center.html父模板页面
{% extends 'base_no_cart.html' %}
{% block title %}天天生鲜-用户中心{% endblock %}
{% block page_title %}用户中心{% endblock %}
{% block body %}
<div class="main_con clearfix">
<div class="left_menu_con clearfix">
<h3>用户中心</h3>
<ul>
<li><a href="{% url 'user:user' %}" {% if page == 'user' %}class="active"{% endif %}>· 个人信息</a></li>
<li><a href="{% url 'user:order' 1 %}" {% if page == 'order' %}class="active"{% endif %}>· 全部订单</a></li>
<li><a href="{% url 'user:address' %}" {% if page == 'address' %}class="active"{% endif %}>· 收货地址</a>
</li>
</ul>
</div>
{# 用户中心右侧的页面 #}
{% block right_content %}{% endblock %}
</div>
{% endblock %}
base_detail_list.html父模板页面
{# 详情 列表页 #}
{% extends 'base.html' %}
{% block body %}
<div class="navbar_con">
<div class="navbar clearfix">
<div class="subnav_con fl">
<h1>全部商品分类</h1>
<span></span>
<ul class="subnav">
{% for type in types %}
<li><a href="{% url 'goods:index' %}#model0{{ forloop.counter }}" class="{{ type.logo }}">{{ type.name }}</a></li>
{% endfor %}
</ul>
</div>
<ul class="navlist fl">
<li><a href="{% url 'goods:index' %}">首页</a></li>
<li class="interval">|</li>
<li><a href="javascript:alert('待开发!');">手机生鲜</a></li>
<li class="interval">|</li>
<li><a href="javascript:alert('待开发!');">抽奖</a></li>
</ul>
</div>
</div>
{# 详情页 列表页 主题内容块#}
{% block main_content %}{% endblock %}
{% endblock %}
注册页面就简化成
{% extends 'base.html' %}
{% block title %}天天生鲜-注册{% endblock %}
{% block topfiles %}
<script type="text/javascript" src="{% static 'js/jquery-1.12.4.min.js' %}"></script>
<script type="text/javascript" src="{% static 'js/register.js' %}"></script>
{% endblock %}
{% block header_con %}{% endblock %}
{% block search_bar %}{% endblock %}
{% block body %}
<body>
<div class="register_con">
<div class="l_con fl">
<a class="reg_logo"><img src="{% static 'images/logo02.png' %}" alt=""></a>
<div class="reg_slogan">足不出户 · 新鲜每一天</div>
<div class="reg_banner"></div>
</div>
<div class="r_con fr">
<div class="reg_title clearfix">
<h1>用户注册</h1>
<a href="{% url 'user:login' %}">登录</a>
</div>
<div class="reg_form clearfix">
<form action="" method="post">
{% csrf_token %}
<ul>
<li>
<label for="user_name">用户名:</label>
<input type="text" name="username" id="user_name">
<span class="error_tip">提示信息</span>
</li>
<li>
<label for="pwd">密码:</label>
<input type="password" name="pwd" id="pwd">
<span class="error_tip">提示信息</span>
</li>
<li>
<label for="cpwd">确认密码:</label>
<input type="password" name="cpwd" id="cpwd">
<span class="error_tip">提示信息</span>
</li>
<li>
<label for="email">邮箱:</label>
<input type="text" name="email" id="email">
<span class="error_tip">提示信息</span>
</li>
<li class="agreement">
<input type="checkbox" name="allow" id="allow" checked="checked">
<label for="allow">同意”天天生鲜用户使用协议“</label>
<span class="error_tip2">提示信息</span>
</li>
<li class="reg_sub">
<input type="submit" value="注 册" name="">
</li>
</ul>
</form>
</div>
{{ errmsg }}
</div>
</div>
</body>
{% endblock %}
登陆页面也简化成
{% extends 'base.html' %}
{% load static %}
{% block title %}天天生鲜-登录{% endblock %}
{% block header_con %}{% endblock %}
{% block search_bar %}{% endblock %}
{% block body %}
<div class="login_top clearfix">
<a href="{% url 'goods:index' %}" class="login_logo"><img src="{% static 'images/logo02.png' %}" alt=""></a>
</div>
<div class="login_form_bg">
<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">
<h1>用户登录</h1>
<a href="{% url 'user:register' %}">立即注册</a>
</div>
<div class="form_input">
<form action="" method="post">
{% csrf_token %}
<input type="text" name="username" class="name_input" placeholder="请输入用户名" value="{{ username }}">
<div class="user_error">输入错误</div>
<input type="password" name="pwd" class="pass_input" placeholder="请输入密码">
<div class="pwd_error">输入错误</div>
<div class="more_input clearfix">
<input type="checkbox" name="remember" {{ checked }}>
<label>记住用户名</label>
<a href="#">忘记密码</a>
</div>
<input type="submit" name="" value="登录" class="input_submit">
</form>
</div>
{{ errmsg }}
</div>
</div>
</div>
{% endblock %}
user_center_info用户中心信息
{% extends 'base_user_center.html' %}
{% block right_content %}
<div class="right_content clearfix">
<div class="info_con clearfix">
<h3 class="common_title2">基本信息</h3>
<ul class="user_info_list">
<li><span>用户名:</span>{{ user.username }}</li>
<li><span>联系方式:</span>{{ address.phone|default:'无默认联系方式' }}</li>
<li><span>联系地址:</span>{{ address.addr|default:'无默认收货地址' }}</li>
</ul>
</div>
<h3 class="common_title2">最近浏览</h3>
<div class="has_view_list">
<ul class="goods_type_list clearfix">
{% for goods in goods_list %}
<li>
<a href="{% url 'goods:detail' goods.id %}"><img src="{{ goods.image.url }}" alt=""></a>
<h4><a href="{% url 'goods:detail' goods.id %}">{{ goods.name }}</a></h4>
<div class="operate">
<span class="prize">¥{{ goods.price }}</span>
<span class="unit">{{ goods.price }}/{{ goods.unite }}</span>
<a href="" class="add_goods" title="加入购物车"></a>
</div>
</li>
{% empty %}
无历史浏览记录
{% endfor %}
</ul>
</div>
</div>
{% endblock right_content %}
user_center_order用户中心订单
{% extends 'base_user_center.html' %}
{% load staticfiles %}
{% block right_content %}
<div class="right_content clearfix">
{% csrf_token %}
<h3 class="common_title2">全部订单</h3>
{% for order in order_page %}
<ul class="order_list_th w978 clearfix">
<li class="col01">{{ order.create_time }}</li>
<li class="col02">订单号:{{ order.order_id }}</li>
<li class="col02 stress">{{ order.status_name }}</li>
</ul>
<table class="order_list_table w980">
<tbody>
<tr>
<td width="55%">
{% for order_sku in order.order_skus %}
<ul class="order_goods_list clearfix">
<li class="col01"><img src="{{ order_sku.sku.image.url }}"></li>
<li class="col02">{{ order_sku.name }}<em>{{ order_sku.price }}元/{{ order_sku.sku.unite }}</em>
</li>
<li class="col03">{{ order_sku.count }}</li>
<li class="col04">{{ order_sku.amount }}元</li>
</ul>
{% endfor %}
</td>
<td width="15%">{{ order.total_price|add:order.transit_price }}(含运费:{{ order.transit_price }})元</td>
<td width="15%">{{ order.status_name }}</td>
<td width="15%"><a href="javascript:;" order_id="{{ order.order_id}}" status="{{ order.order_status }}" class="oper_btn">去付款</a></td>
</tr>
</tbody>
</table>
{% endfor %}
<div class="pagenation">
{% if order_page.has_previous_page %}
<a href="{% url 'user:order' order_page.pervious_page_number %}"> < 上一页</a>
{% endif %}
{% for index in pages %}
{% if index == order_page.number %}
<a href="{% url 'user:order' index %}" class="active">{{ index }}</a>
{% else %}
<a href="{% url 'user:order' index %}">{{ index }}</a>
{% endif %}
{% endfor %}
{% if order_page.has_next_page %}
<a href="{% url 'user:order' order_page.next_page_number %}">下一页></a>
{% endif %}
</div>
</div>
{% endblock %}
{% block bottomfiles %}
<script src="{% static 'js/jquery-1.12.4.min.js' %}"></script>
<script>
$('.oper_btn').each(function () {
// 获取status
status = $(this).attr('status');
if (status == 1) {
$(this).text('去支付')
} else if (status == 4) {
$(this).text('去评价')
} else if (status == 5) {
$(this).text('已完成')
}
})
$('.oper_btn').click(function () {
// 获取status
status = $(this).attr('status');
// 获取订单id
order_id = $(this).attr('order_id');
if (status == 1) {
// 进行支付
csrf = $('input[name="csrfmiddlewaretoken"]').val();
// 组织参数
params = {'order_id': order_id, 'csrfmiddlewaretoken': csrf};
// 发起ajax post请求, 访问/order/pay, 传递参数:order_id
$.post('{% url "order:pay" %}', params, function (data) {
if (data.res === 3) {
// 引导用户到支付页面
window.open(data.pay_url);
// 浏览器访问order/check,获取支付交易结果
// ajax post 传递参数:order_id
$.post("{% url 'order:check' %}", params, function () {
if (data.res === 3) {
alert('支付成功!');
//重新加载
location.reload()
} else {
alert(data.errmsg)
}
})
} else {
alert(data.errmsg)
}
})
} else if (status === 4) {
//其他情况
// 跳转到评价页面
location.href = "/order/comment/" + order_id
}
})
</script>
{% endblock bottomfiles %}
user_center_site用户中心收件地址添加
{% extends 'base_user_center.html' %}
{% block right_content %}
<div class="right_content clearfix">
<h3 class="common_title2">收货地址</h3>
<div class="site_con">
<dl>
<dt>当前地址:</dt>
{% if address %}
<dd>{{ address.addr }} ({{ address.receiver }} 收) {{ address.phone }}</dd>
{% else %}
<dd>无默认地址</dd>
{% endif %}
</dl>
</div>
<h3 class="common_title2">编辑地址</h3>
<div class="site_con">
<form method="post" action="">
{% csrf_token %}
<div class="form_group">
<label>收件人:</label>
<input type="text" name="receiver">
</div>
<div class="form_group form_group2">
<label>详细地址:</label>
<textarea class="site_area" name="addr"></textarea>
</div>
<div class="form_group">
<label>邮编:</label>
<input type="text" name="zip_code">
</div>
<div class="form_group">
<label>手机:</label>
<input type="text" name="phone">
</div>
<input type="submit" name="" value="提交" class="info_submit">
</form>
</div>
</div>
{% endblock right_content %}
from django.contrib.auth.decorators import login_required
from django.views import View
class LoginRequredMixIn(View):
@classmethod
def as_view(cls, **initkwargs):
view = super(LoginRequredMixIn, cls).as_view(**initkwargs)
return login_required(view)
用户试图所有实现
from django.shortcuts import render, redirect, reverse, HttpResponse
from django.views import View
from django.conf import settings
from django_redis import get_redis_connection
from django.contrib.auth import authenticate, login, logout
from user.models import User, Address
from goods.models import GoodsSKU
import re
from itsdangerous import JSONWebSignatureSerializer as Serializer
from itsdangerous import BadSignature
import time
from celery_tasks.task import send_register_mail
from utils.mixin import LoginRequredMixIn
from order.models import OrderInfo, OrderGoods
from django.core.paginator import Paginator
# Create your views here.
class RegisterView(View):
def get(self, request):
return render(request, 'register.html')
def post(self, request):
username = request.POST.get('username')
password = request.POST.get('pwd')
email = request.POST.get('email')
if not all([username, password, email]):
return render(request, 'register.html', {'errmsg': '数据不完整!'})
allow = request.POST.get('allow')
if allow != 'on':
return render(request, 'register.html', {'errmsg': '请同意协议!'})
reg = "[\w!#$%&'*+/=?^_`{|}~-]+(?:\.[\w!#$%&'*+/=?^_`{|}~-]+)*@(?:[\w](?:[\w-]*[\w])?\.)+[\w](?:[\w-]*[\w])?"
if not re.match(reg, email):
return render(request, 'register.html', {'errmsg': '邮箱不合法!'})
if User.objects.filter(username=username):
return render(request, 'register.html', {'errmsg': '用户名已被注册!'})
if User.objects.filter(email=email):
return render(request, 'register.html', {'errmsg': '邮箱已被注册!'})
user = User.objects.create_user(username, email, password)
user.is_active = False
user.save()
serializer = Serializer(settings.SECRET_KEY)
data = {'id': user.id, 'time': time.time()}
token = serializer.dumps(data).decode()
send_register_mail.delay(email, username, token)
return redirect(reverse('user:login'))
class LoginView(View):
def get(self, request):
username = request.COOKIES.get('username', '')
checked = 'checked' if username else ''
return render(request, 'login.html', {'username': username, 'checked': checked})
def post(self, request):
username = request.POST.get('username')
password = request.POST.get('pwd')
if not all([username, password]):
return render(request, 'login.html', {'errmsg': '数据不完整!'})
user = authenticate(username=username, password=password)
if user is None:
return render(request, 'login.html', {'errmsg': '用户名或密码错误!'})
if not user.is_active:
return render(request, 'login.html', {'errmsg': '用户未**!'})
login(request, user)
next_url = request.GET.get('next', reverse('goods:index'))
response = redirect(next_url)
remember = request.POST.get('remember')
if remember == 'on':
response.set_cookie('username', username, max_age=7 * 24 * 3600)
else:
response.delete_cookie('username')
return response
class LogoutView(View):
def get(self, request):
logout(request)
return redirect(reverse('user:login'))
class ActiveView(View):
def get(self, request, token: str):
serializer = Serializer(settings.SECRET_KEY)
try:
data = serializer.loads(token.encode())
user_id = data.get('id')
user = User.objects.get(pk=user_id)
user.is_active = True
user.save()
return redirect(reverse('user:login'))
except BadSignature:
return HttpResponse('错误的请求链接!', status=401)
class UserInfoView(LoginRequredMixIn):
def get(self, request):
# 获取个人信息
address = Address.objects.get_default_address(request.user)
# 获取浏览记录
conn = get_redis_connection('default')
history_key = 'history_%d' % request.user.id
sku_ids = conn.lrange(history_key, 0, 4)
goods_list = []
# 历史浏览记录排序
for sku_id in sku_ids:
goods = GoodsSKU.objects.get(pk=sku_id)
goods_list.append(goods)
context = {
'page': 'user',
'address': address,
'goods_list': goods_list
}
return render(request, 'user_center_info.html', context)
class UserOrderView(LoginRequredMixIn):
def get(self, request, page):
# 获取用户的订单信息
user = request.user
orders = OrderInfo.objects.filter(user=user).order_by('-create_time')
for order in orders:
order_skus = OrderGoods.objects.filter(order_id=order.order_id)
for order_sku in order_skus:
amount = order_sku.count * order_sku.price
order_sku.amount = amount
order.order_skus = order_skus
order.status_name = OrderInfo.ORDER_STATUS[order.order_status]
paginator = Paginator(orders, 1)
# 对页码进行容错处理
try:
page = int(page)
except Exception:
page = 1
if page > paginator.num_pages:
page = paginator.num_pages
order_page = paginator.page(page)
# TODO 页码控制
num_pages = paginator.num_pages
if num_pages < 5:
pages = range(1, num_pages + 1)
elif page <= 3:
pages = range(1, 6)
elif num_pages - page <= 2:
pages = range(num_pages - 4, num_pages + 1)
else:
pages = range(page - 2, page + 3)
context = {
'order_page': order_page,
'pages': pages,
'page': 'order'
}
return render(request, 'user_center_order.html', context)
class AddressView(LoginRequredMixIn):
def get(self, request):
# 获取用户的默认收货地址
address = Address.objects.get_default_address(request.user)
return render(request, 'user_center_site.html', {'page': 'address', 'address': address})
def post(self, request):
receiver = request.POST.get('receiver')
addr = request.POST.get('addr')
zip_code = request.POST.get('zip_code')
phone = request.POST.get('phone')
if not all([receiver, addr, phone]):
return render(request, 'user_center_site.html', {'page': 'address', 'errmsg': '数据不完整!'})
reg = '1([38][0-9]|4[579]|5[0-3,5-9]|6[6]|7[0135678]|9[89])\d{8}'
if not re.match(reg, phone):
return render(request, 'user_center_site.html', {'page': 'address', 'errmsg': '手机号码格式错误!'})
address = Address.objects.get_default_address(request.user)
is_dafault = False if address else True
Address.objects.create(
user=request.user,
receiver=receiver,
zip_code=zip_code,
addr=addr,
phone=phone,
is_default=is_dafault,
)
return redirect(reverse('user:address'))
用户所有跳转页面urls.py
from django.urls import path, re_path
from . import views
app_name = 'user'
urlpatterns = [
path('register', views.RegisterView.as_view(), name='register'),
path('login', views.LoginView.as_view(), name='login'),
path('logout', views.LogoutView.as_view(), name='logout'),
path('active/<token>', views.ActiveView.as_view(), name='active'),
path('', views.UserInfoView.as_view(), name='user'),
path('order/<int:page>', views.UserOrderView.as_view(), name='order'),
path('address', views.AddressView.as_view(), name='address'),
]
主题
from xadmin import views
import xadmin
# 配置xadmin主题
class BaseSettingAdmin(object):
enable_themes = True
use_bootswatch = True
class CommSettingAdmin(object):
site_title = 'Django-天天生鲜后台管理系统'
site_footer = 'ivy'
menu_style = 'accordion' # 折叠样式
# 注册主题类
xadmin.site.register(views.BaseAdminView, BaseSettingAdmin)
# 注册全局样式类
xadmin.site.register(views.CommAdminView, CommSettingAdmin)