基于上一篇博客继续跟进:
Django搭建电商网站之店铺与商品_店铺注册与商品管理(二)
一、添加校验用户是否有店铺的功能
1、在用户登录时下发校验店铺的cookie
在用户登陆校验完成之后校验用户是否拥有店铺
通过校验cookie来证明用户是否拥有店铺
如果店铺存在,则设置cookie is_store为店铺id
如果店铺不存在,则设置cookie为空(这里设置为空是因为前端获取cookie时不论是0还是false都是字符串类型,前端都会判断为真)
2、在base页重新进行前端店铺校验
<!-- Sidebar -->
{% if request.COOKIES.is_store %}
<ul class="navbar-nav bg-gradient-primary sidebar sidebar-dark accordion" id="accordionSidebar">
<!-- Sidebar - Brand -->
<a class="sidebar-brand d-flex align-items-center justify-content-center" href="index.html">
<div class="sidebar-brand-icon rotate-n-15">
<i class="fas fa-laugh-wink"></i>
</div>
<div class="sidebar-brand-text mx-3">后台管理系统</div>
</a>
<!-- Divider -->
<hr class="sidebar-divider my-0">
<!-- Nav Item - Dashboard -->
<li class="nav-item">
{# {% if is_store %}#}
<a class="nav-link" href="#">
<i class="fas fa-fw fa-tachometer-alt"></i>
<span>店铺管理</span></a>
{# {% else %}#}
{# <a class="nav-link" href="/Store/store_register/">#}
{# <i class="fas fa-fw fa-tachometer-alt"></i>#}
{# <span>没有店铺,注册一个</span></a>#}
{# {% endif %}#}
</li>
<!-- Divider -->
<hr class="sidebar-divider">
<!-- Heading -->
<div class="sidebar-heading">
销售管理
</div>
<!-- Nav Item - Pages Collapse Menu -->
<li class="nav-item">
<a class="nav-link collapsed" href="#" data-toggle="collapse" data-target="#collapseTwo" aria-expanded="true" aria-controls="collapseTwo">
<i class="fas fa-fw fa-cog"></i>
<span>商品管理</span>
</a>
<div id="collapseTwo" class="collapse" aria-labelledby="headingTwo" data-parent="#accordionSidebar">
<div class="bg-white py-2 collapse-inner rounded">
<h6 class="collapse-header">商品信息:</h6>
<a class="collapse-item" href="/Store/add_good/">添加商品</a>
<a class="collapse-item" href="/Store/goods_list/">商品列表</a>
</div>
</div>
</li>
<!-- Nav Item - Utilities Collapse Menu -->
<!-- Divider -->
{# <hr class="sidebar-divider">#}
<!-- Nav Item - Charts -->
{# <li class="nav-item">#}
{# <a class="nav-link" href="charts.html">#}
{# <i class="fas fa-fw fa-chart-area"></i>#}
{# <span>图表</span></a>#}
{# </li>#}
<!-- Nav Item - Tables -->
{# <li class="nav-item">#}
{# <a class="nav-link" href="tables.html">#}
{# <i class="fas fa-fw fa-table"></i>#}
{# <span>表格</span></a>#}
{# </li>#}
<!-- Divider -->
{# <hr class="sidebar-divider d-none d-md-block">#}
<!-- Sidebar Toggler (Sidebar) -->
<div class="text-center d-none d-md-inline">
<button class="rounded-circle border-0" id="sidebarToggle"></button>
</div>
</ul>
<!-- End of Sidebar -->
{% else %}
<ul class="navbar-nav bg-gradient-primary sidebar sidebar-dark accordion" id="accordionSidebar">
<!-- Sidebar - Brand -->
<a class="sidebar-brand d-flex align-items-center justify-content-center" href="index.html">
<div class="sidebar-brand-icon rotate-n-15">
<i class="fas fa-laugh-wink"></i>
</div>
<div class="sidebar-brand-text mx-3">后台管理系统</div>
</a>
<!-- Divider -->
<hr class="sidebar-divider my-0">
<!-- Nav Item - Dashboard -->
<li class="nav-item">
<a class="nav-link" href="/Store/store_register/">
<i class="fas fa-fw fa-tachometer-alt"></i>
<span>没有店铺,注册一个</span></a>
</li>
<!-- Divider -->
<hr class="sidebar-divider">
<div class="text-center d-none d-md-inline">
<button class="rounded-circle border-0" id="sidebarToggle"></button>
</div>
</ul>
{% endif %}
店铺校验的大致流程:
3、后端店铺注册视图同时也进行下发cookie is_store
效果展示:
重新注册一个后台用户进行登录测试:
注册店铺:
注册店铺成功后自动跳转到首页:
此时左侧功能区店铺管理已经显示(识别此用户有店铺,通过is_store),可以进行相关店铺功能操作了
二、业务逻辑实现:查看商品列表是针对当前用户的店铺
1、更改添加商品页面的店铺id(隐藏域)为自动获取cookie,每次添加商品的时候就会自动关联当前页面cookie中的店铺id
解决店铺和商品的依赖关系
<div class="form-group">
<input type="hidden" class="form-control form-control-user" name="store_id" value="{{ request.COOKIES.is_store }}">
</div>
2、修改后端商品列表视图,使用多对多关系反向查询
基于当前店铺添加商品信息,返回的商品应该当前店铺的商品
三、新增商品下架功能
1、商品模型类添加商品状态字段,并同步数据库
使用goods_under作为商品状态字段,1为上架,2为待售状态
# v2.4 新增商品状态字段;1 待售 0 下架
goods_under = models.IntegerField(verbose_name="商品状态",default=1)
2、更改商品列表视图,filter中新增条件只查询上架商品
这样前端商品列表只会显示上架的商品
3、更新商品列表前端页面下架标签
我们通过点击商品列表页的商品信息后的下架按钮触发下架的视图函数,并通过参数id来发送当前的商品id至后端来关联要下架的具体商品
<a class="btn btn-danger" href="/Store/goods_under/?id={{ goods.id }}">下架</a>
4、新增商品下架视图函数
获取前端get请求中的id参数,来查询需要下架哪个商品,将商品状态置为0,下架完成后通过request.META中的HTTP_REFERER参数获取请求的来源地址,最后返回上一个请求的页面
# v2.4 新增商品上架功能
def under_goods(request):
id = request.GET.get("id")
# v2.4 返回当前请求的来源地址
referer = request.META.get("HTTP_REFERER")
if id:
# v2.4 获取指定id的商品(保险实现filter,get如果id不存在容易报错)
goods = Goods.objects.filter(id=id).first()
# v2.4 修改商品状态
goods.goods_under = 0
goods.save()
return HttpResponseRedirect(referer)
四、商品上架及销毁功能
下架的商品不可能凭空消失,我们也不可能将下架的商品从数据库中直接删除,我们需要一个可以查询到下架的商品的地方,当有需求了,可以再将下架的商品进行上架或销毁
后台新增下架的商品列表页面及选项
1、base页新增下架商品的选项
<div class="bg-white py-2 collapse-inner rounded">
<h6 class="collapse-header">商品信息:</h6>
<a class="collapse-item" href="/Store/add_good/">添加商品</a>
<a class="collapse-item" href="/Store/goods_list/up/">在售商品列表</a>
<a class="collapse-item" href="/Store/goods_list/down/">下架商品列表</a>
</div>
2、为了使上下架商品列表不出现代码冗余,对商品列表视图及前端进行状态判断共用一个视图和前端页面
通过url请求的状态来修改数据库完成上架和下架以及销毁的功能
为了避免使用数据前端将其装换为字符类型,我们直接使用单词字母进行表示判断,当状态参数state为“up”时,代表查询的是上架商品,查询时商品状态为1的所有商品;否则就是查询下架的商品,查询的是商品状态为0的商品。
子url进行正则组命名传递参数:
3、将前面的under_goods视图该为set_goods,对页面上下架按钮提交做判断进行相应的处理。同时将销毁功能也编写出来
同样根据商品列表类似,添加状态参数,新增一个state为delete。只要状态参数为delete则就是删除该商品
# v2.4 新增商品上架功能
def set_goods(request,state):
# v2.5 使该视图同时具备上下架及销毁的功能
if state == "up":
state_num = 1
else:
state_num = 0
id = request.GET.get("id")
# v2.4 返回当前请求的来源地址
referer = request.META.get("HTTP_REFERER")
if id:
# v2.4 获取指定id的商品
goods = Goods.objects.filter(id=id).first()
# v2.5 判断前端路由中的字段参数来进行相应的操作,这里如果为delete,删除该商品
if state == "delete":
goods.delete()
else:
# v2.4 修改商品状态
goods.goods_under = state_num
goods.save()
return HttpResponseRedirect(referer)
同样的定义好请求的路由:
商品列表页面进行ifequal判断,如果state为up表明为上架的商品,可以进行的操作就是下架商品,点击下架就会触发/Store/set_goods/down/?id={{ goods.id }}路由,再进入视图函数处理,将商品状态置为0
否则可以进行的操作就是上架商品,点击上架就会触发/Store/set_goods/up/?id={{ goods.id }}路由,再进入视图函数处理,将商品状态置为1
销毁功能是针对上下架商品都具备的功能,所以不论在售商品列表还是下架商品列表都具备商品销毁功能
{% ifequal state 'up' %}
<a class="btn btn-danger" href="/Store/set_goods/down/?id={{ goods.id }}">下架</a>
{% else %}
<a class="btn btn-danger" href="/Store/set_goods/up/?id={{ goods.id }}">上架</a>
{% endifequal %}
<a class="btn btn-primary" href="/Store/set_goods/delete/?id={{ goods.id }}">销毁</a>
GitHub项目地址:https://github.com/py304/DjangoShop