当前位置:网站首页>基于flask实现的mall商城---用户模块
基于flask实现的mall商城---用户模块
2022-07-29 10:51:00 【头发慢点掉的小马】
1.功能分析
1.注册登录退出
2.订单相关:
我的订单查看
查询订单
删除订单
3.购物车court:
加入购物车
删除商品
4.搜索商品
5.浏览商品(查看所有商品)
6.购买商品
7.用户充值
8.VIP:
购买VIP
查看自己VIP情况
2.基本实现
from datetime import datetime
from flask import Blueprint, request, jsonify, session
from blueprints.forms import RegisterForm
from decorators import login_required
from exts import db
from models import User, Goods, Receipt, VipReceipt, Court, ReceiptItem, Comment
from utils import result, getOrderNum, getNowDataTime
bp = Blueprint("user", __name__, url_prefix="/user")
@bp.route('/register', methods=['GET', 'POST'])
def register():
if request.method == 'GET':
return "register.html"
else:
form = RegisterForm(register.form)
if form.validate():
print("验证成功")
username = form.username.data
password = form.password.data
print(username, password)
# 密码加密
# hash_password = generate_password_hash(password=password)
create_time = datetime.now()
# 1.通过username查询user表 如果存在就通知已存在该用户 不存在就新建
user_model = User.query.filter_by(username=username).first()
if user_model:
print("该用户名已被注册,请重新输入")
return jsonify({"code": 401, "message": "该用户名已被注册,请重新输入"})
user = User(username=username, password=password, createTime=create_time)
db.session.add(user)
db.session.commit()
return jsonify({"code": 200, "message": "user 注册成功"})
else:
print("注册验证失败")
return jsonify({"code": 401, "message": "注册验证失败"})
# 用户充值
@bp.route("/balance", methods=["POST"])
@login_required
def balance():
if request.method == "POST":
balance = request.form["balance"]
sId = session.get("_id")
user = User.query.get(sId)
try:
user.balance = user.balance + balance
except:
user.balance = balance
db.session.commit()
return result()
"""
商品相关:
1. 浏览商品(就是获取所有商品)分页查询
2. 搜索商品(按名称搜索) 实际上就是sql语句like查询
3. 购买商品 将商品添加到订单表中
"""
@bp.route("/goodList/<int:page>", methods=['POST'])
def goodList(page):
# page表示第几页
goodList = Goods.query.limit(10).offset((page - 1) * 10)
data = dict()
data['data'] = []
for good in goodList:
dic = good.__dict__
del dic["_sa_instance_state"]
data["data"].append(dic)
return result(200, data)
@bp.route("/search", methods=['POST'])
def search():
searchItem = request.form.get('searchItem')
goodList = Goods.query.filter_by(Goods.name.contains(searchItem)).limit(50)
data = dict()
data['data'] = []
for good in goodList:
data["data"].append({
"id": good._id,
"name": good.name,
"originPrice": good.originPrice,
"sellPrice": good.sellPrice,
"image": good.image,
"lookTimes": good.lookTimes,
"likeTimes": good.likeTimes,
"buyTimes": good.buyTimes,
})
return result(200, data, message="获取数据成功")
"""
两种方式购买:
1.直接就可以购买:此时传入的数据就是订单的id 将这个商品信息加入到订单表中
2.通过购物车购买"""
@bp.route("/buyGood/<int:goodId>")
@login_required
def buy(goodId):
sId = session.get("_id", None)
form = request.form
user = User.query.get(sId)
if user.balance < form["payValue"]:
return result(204, {"info": "余额不足"})
user.balance = user.balance - form["payValue"]
if goodId:
good = Goods.query.filter_by(_id=goodId).first()
receiptItem = ReceiptItem(goodsId=good['id'], number=1)
db.session.add(receiptItem)
data = {
"orderNum": getOrderNum(),
"createTime": getNowDataTime(),
"payValue": form["payValue"],
"cutoffValue": form["cutoffValue"],
"user_id": sId,
}
receipt = Receipt(**data)
db.session.add(receipt)
db.session.commit()
return result(200)
else:
# 从购物车购买
goodsList = request.form["goodsList"]
itemIdList = []
itemCount = ReceiptItem.query.count()
# 购物车清空
court = Court.query.filter_by(user_id=sId).first()
for goods in goodsList:
item = ReceiptItem(goodsId=goods["id"], number=goods["number"])
db.session.add(item)
goods = Goods.query.get(goods["id"])
court.goods.remove(goods)
goods.buyTimes = goods.buyTimes + 1
goods.contains = goods.contains - 1
itemCount = itemCount + 1
itemIdList.append(itemCount)
data = {
"orderNum": getOrderNum(),
"createTime": getNowDataTime(),
"payValue": form["payValue"],
"cutoffValue": form["cutoffValue"],
"user_id": sId,
"itemId": str(itemIdList)
}
receipt = Receipt(**data)
db.session.add(receipt)
db.session.commit()
return result(200)
# 购买VIP
@bp.route("/buyVIP", methods=['POST'])
@login_required
def buyVIP():
if request.method == 'POST':
form = request.form
sId = session.get("_id")
user = User.query.filter_by(_id=sId).first()
vipR = VipReceipt.query.filter_by(user_id=sId).first()
if vipR:
if user.balance < form.get("payValue"):
return result(203, message="余额不足")
else:
user.balance = user.balance - form["payValue"]
data = {
"orderNum": getOrderNum(),
"createTime": getNowDataTime(),
"payValue": form["payValue"],
"cutoffValue": form["cutoffValue"],
"user_id": sId,
"vipId": form["vipId"]
}
print(data)
r = VipReceipt(**data)
user.vip = form["vipId"]
db.session.add(r)
db.session.commit()
return result(200, message="VIP购买成功")
else:
return result(206, message="该用户已经是VIP,不需要重复购买")
# 查看自己VIP购买情况
@bp.route("/self/vip")
@login_required
def self_vip():
sId = session.get("_id")
vipR = VipReceipt.query.filter_by(user_id=sId).first()
if vipR:
data = dict()
data['data'] = []
dic = vipR.__dict__
del dic["_sa_instance_state"]
data["data"].append(dic)
return result(200, data, message="获取数据成功")
else:
return result(205, message="该用户没有购买VIP")
"""
订单相关
1. 查询自己的订单
2. 删除订单
"""
@bp.route("/self/receipt")
@login_required
def selfReceipt():
sId = session.get("_id", None)
receiptList = Receipt.query.filter_by(user_id=sId).all
data = dict()
data['data'] = []
for receipt in receiptList:
goodsIdList = receipt.get_goods_id_list()
dic = receipt.__dict__
del dic["_sa_instance_state"]
dic["createTime"] = dic["createTime"].strftime("%Y-%m-%d")
dic["goodsList"] = []
for goodsId in goodsIdList:
goods = Goods.query.get(goodsId)
d = {
"name": goods.name,
"originPrice": goods.originPrice,
"sellPrice": goods.sellPrice
}
print("=" * 30)
print(d)
print("=" * 30)
dic["goodsList"].append(d)
data["data"].append(dic)
return result(200, data)
@bp.route("/delete/receipt/<int:receiptId>")
@login_required
def deleteReceipt(receiptId):
sId = session.get("_id", None)
# 必须要userId和订单id均符合才能删除
Receipt.query.filter_by(_id=receiptId, user_id=sId).delete()
return result(200, meaasge="删除商品订单成功")
# 购物车相关
@bp.route("/addCourt")
@login_required
def addCourt():
goodsId = request.form["goodsId"]
sId = session["_id"]
court = Court.query.filter_by(user_id=sId).first()
court.number = court.number + 1
goods = Goods.query.get(goodsId)
goods.likeTimes = goods.likeTimes + 1
court.goods.append(goods)
db.session.commit()
return result(200)
@bp.route("/remove/goodFromCourt/<int:goodId>")
@login_required
def removeGoodFromCourt(goodId):
sId = session.get("_id")
court = Court.query.filter_by(user_id=sId).first()
court.number = court.number - 1
good = Goods.query.filter_by(_id=goodId).first()
if good.likeTimes > 0:
good.likeTimes = good.likeTimes - 1
court.goods.remove(good)
return result(200, message="商品从购物车中删除成功")
# 给商品评论
@bp.route("/comment/<int:goodId>")
@login_required
def comment(goodId):
sId=session.get("_id")
form=request.form
data = {
"createTime": getNowDataTime(),
"content": form["content"],
"cutoffValue": form["cutoffValue"],
"user": sId,
"good": goodId
}
comment = Comment(**data)
db.session.add(comment)
db.session.commit()
return result(200,message="评论成功")
3.权限控制
主要是为了限制用户未登录的状态不能访问一些网站,比如用户未登录的时候不能进行加入购物车等。这里主要是利用装饰器来进行实现
"""装饰器"""
from flask import g, redirect, url_for
from functools import wraps
"""如果没有登录就不能访问,跳转到登录页面 如果登录了就正常逻辑处理"""
def login_required(func):
@wraps(func)
def wrapper(*args, **kwargs):
if hasattr(g, "_id"):
return func(*args, **kwargs)
else:
print("未登录不能进行访问")
return redirect(url_for("user.login"))
return wrapper
4. 表单验证
在前端传过来的参数,后端要先进行参数验证是否符合要求。利用wtforms进行验证
import os
import sys
TESTCASE=os.path.dirname(os.path.abspath(__file__))
DIR=os.path.dirname(TESTCASE)
sys.path.append(DIR)
import wtforms
from wtforms.validators import length, email, EqualTo, InputRequired, NumberRange, AnyOf
class LoginForm(wtforms.Form):
account = wtforms.StringField(validators=[length(min=0,max=14)])
password = wtforms.StringField(validators=[length(min=6,max=20)])
type=wtforms.StringField(validators=[length(0,10)])
class RegisterForm(wtforms.Form):
username = wtforms.StringField(validators=[length(min=3,max=20,message="长度在3和20之间")])
password = wtforms.StringField(validators=[length(min=6,max=20,message="长度在6和20之间")])
password_confirm = wtforms.StringField(validators=[EqualTo("password")])
class UpdateUserForm(wtforms.Form):
username = wtforms.StringField(validators=[length(min=3, max=20, message="长度在3和20之间")])
gneder=wtforms.StringField(validators=[AnyOf("男","女")])
class AddGoodsForm(wtforms.Form):
name=wtforms.StringField(validators=[length(min=0,max=50,message="长度在0和50之间")])
边栏推荐
- Research on Android multithreading (4) -- from an interview question
- Survival analysis using rtcga clinical data
- StarRocks 技术内幕:实时更新与极速查询如何兼得
- Atomic operation of day4 practice in 2022cuda summer training camp
- 牛客网刷题
- 开放原子开源基金会秘书长孙文龙 | 凝心聚力,共拓开源
- Discussion on the application of arcing smart electricity in elderly care institutions
- 1. (map tools) detailed tutorial of acrgis desktop10.5 software installation
- 2022cuda summer training camp Day5 practice
- factoextra:多元统计的可视化
猜你喜欢

VMware: use commands to update or upgrade VMware esxi hosts

Factoextra: visual PCA of multivariate statistical methods

开源峰会抢先看 | 7月29日分论坛&活动议程速览

Zhou Hongyi: 360 is the largest secure big data company in the world

How to realize the function of adding watermark

Detailed arrangement of JVM knowledge points (long text warning)

Review of the 16th issue of HMS core discovery | play with the new "sound" state of AI with tiger pier

Pytorch 入门

Learning R language these ebooks are enough!

牛客网刷题
随机推荐
DOD and Dor, two artifacts to reduce "cognitive bias"
DoD 和 DoR,消减「认知偏差」的两大神器
Research on the realization of linear gradient circular progress bar
Hugo NexT V4 介绍
2022cuda summer training camp day3 practice
Conference OA project - my approval
Create PHP message board system with kubernetes
factoextra:多元统计方法的可视化PCA
就这?TypeScript其实并不难!(建议收藏)
The server
Ggdag draw DAG and cause and effect diagram
专访 | 阿里巴巴首席技术官程立:云 + 开源共同形成数字世界的可信基础
带你浅聊一下PHP搭建的电商商城系统
Summer 2022 software innovation laboratory training JDBC
数据可视化设计指南(信息图表篇)
Oncopy and onpaste
阿里P8爆出的这份大厂面试指南,看完工资暴涨30k!
美团、饿了么被杭州市监约谈要求落实食品安全管理责任 严禁恶意竞争
Analysis of QT basic engineering
Use tidymodels to solve the binary logistic model