elm_flask前台管理项目日志
前台管理项目日志
项目分析
-
前后端分离,后端根据前端提供的api接口向前端提供json数据,进行数据的渲染
-
app绑定后台系统数据库
-
redis配置,作为缓存使用
redis的配置
def get_redis():
from redis import Redis
return Redis(host='主机号', port=端口号) # 可以使用远程的服务器
项目需求:
商家模块
-
提供首页店铺的所有相关信息
-
根据shop的id值提供店铺中的所有商品详情信息
// 获得商家列表接口(python)
businessList: '/api/v1/shop_list/',
// 获得指定商家接口(python)
business: '/api/v1/shop/',
- 设置模型类,字典化字段名和值,减少挨个字段复制的冗余度
# 模型类的设置
class Shop(BaseModel):
shop_name = db.Column(db.String(100), comment='店铺名称')
shop_img = db.Column(db.String(200), comment='店铺图片', default="")
.......
# return字段名
def keys(self):
return "shop_name","shop_img"
# 将字段名自动匹配返回一个字典格式的键值对
def __getitem__(self, item):
if hasattr(self, item):
return getattr(self, item)
- 使用列表生成式来构建一个字典,通过**dict() 进行解包,给字典添加其他键值
data = [{**dict(shop), "id": shop.pub_id} for shop in shops]
用户模块
-
用户注册,表单验证手机号是否符合规范,后端可以采用正则进行验证,
-
验证码api,使用随机random模块生成随机码,并将随机码保存到redis中
-
用户登录,根据前端传来的表单值,查询数据库,查看用户是否存在,存在则进行返回json信息,登录时需要保存token值,使用TimedJSONWebSignatureSerializer 生成签名序列,并将token保存到cookie中
-
新增地址,接收表单数据,进行数据库的存储,关联user_id
-
修改地址,根据地址的id进行指定地址的修改
-
修改密码,获取当前登录用户,验证原密码的正确性,进行密码的修改
-
忘记密码,验证手机号是否符合规范,根据手机号获取到唯一的用户,进行密码的重置
// 登录验证接口(python)
loginCheck: '/api/v1/login/',
// 获取短信验证码接口(python)
sms: '/api/v1/sms/',
// 注册接口(python)
regist: '/api/v1/register/',
// 地址列表接口(python)
addressList: '/api/v1/address/',
// 指定地址接口 (python,查看某一个地址,利用id参数传递)
address: '/api/v1/address/',
// 保存新增地址接口(python)
addAddress: '/api/v1/address/',
// 保存修改地址接口 (python)
editAddress: '/api/v1/address/',
// 修改密码接口
changePassword: '/api/v1/password/',
// 忘记密码接口
forgetPassword: '/api/v1/new_password/',
- token的设置
from itsdangerous import TimedJSONWebSignatureSerializer as Serializer, SignatureExpired, BadSignature
# 登录成功时,设置token.token:登录标识,携带用户买家的id号
# TimedJSONWebSignatureSerializer("**","过期时间")
serializer = Serializer(current_app.config.get("SECRET_KEY"))
token = serializer.dumps({"buyid": buyer.id})
data = {
"status": "true",
"message": "登录成功",
"user_id": buyer.id,
"username": buyer.username,
}
# api返回信息
response = jsonify(data)
# 将token保存到cookie中
response.set_cookie("x-access-token", token.decode('utf-8'))
- 检查token是否存在,如果存在则提供数据
def check_token(fun):
@wraps(fun)
def inner(*args, **kwargs):
if "Cookie" in request.headers:
# 通过cookie取出token值
token = request.cookies.get('x-access-token')
else:
return jsonify({"status": "false", "message": "没有可用的token"})
ser = Serializer(current_app.config.get('SECRET_KEY'))
try:
# 将保存在token中的数据取出来
data = ser.loads(token)
# 捕捉异常
except SignatureExpired:
return jsonify({"status": "false", "message": "token过期"})
except BadSignature:
return jsonify({"status": "false", "message": "token不可用"})
buyerid = data.get("buyid")
buyer = db.session.query(Buyer).filter_by(id=buyerid).first()
if not buyer:
return jsonify({"status": "false", "message": "用户非法"})
# g 全局的类,可以在其他地方直接使用
g.buyerid = buyerid
g.buyer = buyer
re = fun(*args, **kwargs)
return re
return inner
- 收货地址api返回json时,address的id按每人用户的注册地址依次排序,例如:1号用户添加地址在数据库中的id为1,4.如何在传递id时以1,2来排序,而不是直接传递真实的地址id值
@api_bp.route('/address/', endpoint='address', methods=['GET'])
@check_token
def get_address_list():
address = g.buyer.address
num = request.args.get("id")
# 判断是否有id值,得到具体一个地址的信息
if num:
# 根据传递的id从当前用户的地址列表取出对应的那一条
data = {**dict(address[int(num) - 1])}
return jsonify(data)
# address为当前用户的地址列表,使用enumerate可以拿到从0排序的地址
data = [{**dict(add), "id": int(num) + 1} for num, add in enumerate(address)]
return jsonify(data)
购物车模块
- 购物车数据保存至redis中,订餐系统的购物车应该有时效性
- 购物车应该只保存一个店铺的商品信息,在反复添加购物车时,应该清除购物车中的数据在进行保存
- 使用hash对象存储购物车的数据,在生成订单之后删除redis中保存的数据值
- 设计订单表,订单表保存的是下单时刻的具体信息,所以订单表的部分数据应该直接保存为字符串,以免数据库的变动,导致订单的信息发生改变,比如收货地址,商品价格等,应该为当时的信息.订单表应该关联买家用户表,一个买家多个订单.
- 订单商品表,关联订单表和商品详情表,一个订单对应多个商品.
// 保存购物车接口(python)
addCart: '/api/v1/cart/',
// 获取购物车数据接口(python)
cart: '/api/v1/cart/',
// 获得订单列表接口
orderList: '/api/v1/orders/',
// 获得指定订单接口
order: '/api/v1/order/',
// 添加订单接口
addOrder: '/api/v1/order/',
列表推导式的使用,可以减少冗余代码,
发送json时,使用**dict()需要保证数据库的字段名与前端接收的数据名相同,否则应该挨个赋值
api文档地址
https://www.showdoc.cc/246851481236416?page_id=1407584097589247