后台页面实现店铺管理
效果图
后台主页
登出
店铺管理
展示店铺页面
添加店铺后
修改店铺信息
修改后会跳转到主页
在此点商品店铺后就会展示修改后的内容
项目步骤
后台主页
做之前先分析逻辑:
- 管理员必须登录后才能进入属于自己后台管理页面,不能还没登录就能直接访问后台管理页面
- 所以需要添加一个装饰器来确认那些只能登陆后才能访问的页面是否可以访问
- 确认条件必然是具有某种特殊且唯一标识身份的东西,我们可以通过seller表中来寻找,从而发现唯一标识莫过于seller的id,所以我们以seller的id作为其身份的象征
- 如何存储seller的id,一般情况在我们可以通过缓存进行存储
- 在浏览器中缓存莫过于cookie或者session,一般情况存储用户信息都是用session,因为session会自动进行加密,但是作者这里为了方便直接cookie进行校验,因为其展示明文好方便我们进行访问和查阅
- 当我们登出后则需要清除后台用户在浏览器中所有缓存
根据上面的逻辑也就接受了在上篇文章的视图函数中登录功能会加上以下代码
这里主要是登录成功后,为浏览器生成缓存以便身份校验
登录装饰器
project01/views.py
#新加代码
from functools import wraps
def login_Decorator(func):
@wraps(func)
def inner(request):
if request.COOKIES.get("seller_id"):
return func(request)
return redirect("/seller/login")
return inner
首页
因为我们还没有实现前台的各个功能所以这里首页界面传参很少
project01/views.py
#新加代码
# 首页
@login_Decorator
def index(request):
return render(request,"seller/index.html")
登出
project01/views.py
#新加代码
#登出
def logout(request):
response = redirect('/seller/login')
response.delete_cookie('seller_id')
response.delete_cookie('seller_name')
response.delete_cookie('seller_headimg')
return response
写完视图函数后一定要为视图添加路由以免浏览器无法访问
project01/urls.py
....
urlpatterns = [
#原有
path('login', views.login), # 登录
path('register', views.register), # 注册
#新加代码
path('', views.index), # 后台首页
path('index', views.index), # 后台首页
path('logout', views.logout), # 登出
]
效果图
当我们在没有登录时直接访问首页
自动跳转到登录界面
登录成功
登出
店铺管理
逻辑分析
店铺与卖家的对应关系
一般情况下一个卖家只有一个属于自己的品牌名称(除了收购其他公司等特殊情况),所以初步认定店铺和卖家属于一对一关系
页面Get请求
当该卖家没有店铺时则需要展示进行添加店铺页面信息
当该卖家有店铺时则需要展示店铺信息
通过上面的 分析可以判断,单独的店铺详情界面需要进行以下操作
- 建立店铺数据库表
- 展示添加店铺信息操作
- 添加店铺信息操作
- 展示店铺信息操作
- 修改店铺信息操作
代码实现
建立店铺数据库表
project01/models.py
......
#新加代码
# 店铺
class Store(models.Model):
# id 默认会自动添加
name = models.CharField(max_length=32) # 店铺名称
address = models.CharField(max_length=128) # 地址
desc = models.CharField(max_length=128) # 描述
logo = models.ImageField(upload_to='seller', default='1.jpg') # logo
# 店铺和卖家是一对一关系
# to:属性是关联的表格名称,on_delete属性是删除策略,级联删除
seller = models.OneToOneField(to='Seller', on_delete=models.CASCADE)
更新数据库
python manage.py check
python manage.py makemigrations
python manage.py migrate
展示添加店铺信息操作
简单的理解就是将页面展示出来
project01/views.py
....
#店铺
def store(request):
return render(request, "seller/store.html")
配置路由
project01/urls.py
urlpatterns = [
path('', views.index), # 后台首页
path('index', views.index), # 后台首页
path('login', views.login), # 登录
path('register', views.register), # 注册
path('logout', views.logout), # 登出
#新加
path('store', views.store), # 店铺页面
]
添加店铺信息操作
添加店铺信息前要先确认前端会传那些数据到后台来,看是否有缺少
project01/views.py
#店铺
def store(request):
# 获取当前用户的ID
seller_id = request.COOKIES.get("seller_id")
if request.method=="POST":
shopname = request.POST.get("shopname")
shopaddress = request.POST.get("shopaddress")
shopdesc = request.POST.get("shopdesc")
shopimg = request.FILES.get("shopimg")
#添加
store=Store.objects.create(name=shopname,address=shopaddress,desc=shopdesc,logo=shopimg,seller_id=seller_id)
store.save()
return redirect("/seller/index")
return render(request, "seller/store.html")
填入数据后点击添加
展示店铺信息操作
当添加完数据后就应该展示数据
def store(request):
# 获取当前用户的ID
seller_id = request.COOKIES.get("seller_id")
if request.method=="POST":
shopname = request.POST.get("shopname")
shopaddress = request.POST.get("shopaddress")
shopdesc = request.POST.get("shopdesc")
shopimg = request.FILES.get("shopimg")
#添加
store=Store.objects.create(name=shopname,address=shopaddress,desc=shopdesc,logo=shopimg,seller_id=seller_id)
store.save()
return redirect("/seller/index")
#新加代码
#当请求是Get请求时,判断该卖家是否已经有自己的店铺
else:
try:
shop_obj=Seller.objects.get(id=seller_id).store
except:
#如果没有则返回添加店铺信息界面
return render(request, "seller/store.html")
#如果有这返回店铺信息
return render(request,"seller/store.html",{"shop_obj":shop_obj})
修改店铺信息操作
因为修改和添加都在同一个页面下,所以需要判断其操作是修改还是添加
判断其唯一标识在于store的id是否存在,如果不存在则表示该卖家没有店铺所以要进行添加,如果存在则需要进行修改
所以需要向表单传入store的id,如果没有这里会默认为空,有则会value=store_id
projet01/views.py
....
#店铺
def store(request):
# 获取当前用户的ID
seller_id = request.COOKIES.get("seller_id")
if request.method=="POST":
shopname = request.POST.get("shopname")
shopaddress = request.POST.get("shopaddress")
shopdesc = request.POST.get("shopdesc")
shopimg = request.FILES.get("shopimg")
id=request.POST.get("id")
#新加代码
if not id:
#添加
store=Store.objects.create(name=shopname,address=shopaddress,desc=shopdesc,logo=shopimg,seller_id=seller_id)
else:
store=Store.objects.get(id=id)
# 删除以前的照片,当前台传入的图片不为空
if shopimg!=None:
img_path = store.logo.name
path = 'static/img/' + img_path
os.remove(path)
else:
# 如果为空则保持原有图片
shopimg=store.logo
store.name=shopname
store.address = shopaddress
store.desc = shopdesc
store.logo = shopimg
store.save()
return redirect("/seller/index")
else:
try:
shop_obj=Seller.objects.get(id=seller_id).store
except:
return render(request, "seller/store.html")
return render(request,"seller/store.html",{"shop_obj":shop_obj})