技术标签: python 毕业设计 推荐系统 biyesheji0001 biyesheji0002 flask 商品推荐 课程设计 大数据
博主介绍:全网粉丝10W+,前互联网大厂软件研发、集结硕博英豪成立工作室。专注于计算机相关专业毕业设计项目实战6年之久,选择我们就是选择放心、选择安心毕业感兴趣的可以先收藏起来,点赞、关注不迷路
毕业设计:2023-2024年计算机专业毕业设计选题汇总(建议收藏)
毕业设计:2023-2024年最新最全计算机专业毕设选题推荐汇总
项目技术栈:
Python语言、Flask框架、MySQL数据库、HTML
(1)商品分类
(2)系统首页
(3)商品购物车功能
(4)我的购物车
(5)我的商品订单
(6)后台管理登录
(7)后台数据管理界面
一个完整的在线购物商城系统通常包括多个功能模块,涉及用户管理、商品管理、购物车、订单处理、支付等方面。下面是一个基本的功能介绍:
1.用户注册和登录:
2.允许用户注册账户,提供用户名、密码、邮箱等信息。已注册用户可以通过登录进入系统,通常使用Flask的用户认证插件来管理用户身份。
3.商品管理:
4.提供商品列表,展示商品的基本信息,如名称、描述、价格等。
5.具备商品分类功能,使用户能够方便地浏览和搜索商品。
6.购物车功能:
7.用户可以将喜欢的商品添加到购物车中,实时更新购物车的商品数量和总价。
8.允许用户调整购物车中商品的数量或删除不需要的商品。
9.订单处理:
10.用户可以查看已下的订单,订单中包含购买的商品、数量、总价等信息。
11.提供订单状态,例如已支付、待发货、已发货等。
12.允许用户取消未支付的订单。
13.支付系统:
14.整合支付系统,允许用户选择支付方式(如信用卡、支付宝、微信支付等)进行支付。
15.处理支付成功或失败的反馈,确保订单状态正确更新。
16.用户个人中心:
17.提供用户个人信息的管理,包括修改密码、更改个人资料等。
18.用户可以查看订单历史记录和当前的购物车状态。
19.商品详情页:
20.提供详细的商品信息,包括商品图片、规格、用户评价等。
21.允许用户加入购物车或直接购买。
22.搜索和过滤:
23.提供搜索功能,让用户通过关键字查找商品。
24.允许用户通过价格、品牌、类别等条件过滤商品列表。
25.推荐系统:
26.可选的功能,通过用户历史购买记录或浏览行为,向用户推荐可能感兴趣的商品。
27.后台管理:
28.管理员可以对商品信息、用户信息、订单状态等进行管理和监控。
29.提供数据统计功能,如销售报表、用户活跃度等。
30.安全性和用户体验:
31.保障用户数据的安全性,包括密码加密存储、安全的用户会话管理等。
32.提供友好的用户界面,确保用户在购物过程中的流畅体验。
# _*_ coding: utf-8 _*_
from . import home
from app import db
from app.home.forms import LoginForm,RegisterForm,PasswordForm
from app.models import User ,Goods,Orders,Cart,OrdersDetail
from flask import render_template, url_for, redirect, flash, session, request,make_response
from werkzeug.security import generate_password_hash
from functools import wraps
import random
import string
from PIL import Image, ImageFont, ImageDraw
from io import BytesIO
def rndColor():
'''随机颜色'''
return (random.randint(32, 127), random.randint(32, 127), random.randint(32, 127))
def gene_text():
'''生成4位验证码'''
return ''.join(random.sample(string.ascii_letters+string.digits, 4))
def draw_lines(draw, num, width, height):
'''划线'''
for num in range(num):
x1 = random.randint(0, width / 2)
y1 = random.randint(0, height / 2)
x2 = random.randint(0, width)
y2 = random.randint(height / 2, height)
draw.line(((x1, y1), (x2, y2)), fill='black', width=1)
def get_verify_code():
'''生成验证码图形'''
code = gene_text()
# 图片大小120×50
width, height = 120, 50
# 新图片对象
im = Image.new('RGB',(width, height),'white')
# 字体
font = ImageFont.truetype('app/static/fonts/arial.ttf', 40)
# draw对象
draw = ImageDraw.Draw(im)
# 绘制字符串
for item in range(4):
draw.text((5+random.randint(-3,3)+23*item, 5+random.randint(-3,3)),
text=code[item], fill=rndColor(),font=font )
return im, code
@home.route('/code')
def get_code():
image, code = get_verify_code()
# 图片以二进制形式写入
buf = BytesIO()
image.save(buf, 'jpeg')
buf_str = buf.getvalue()
# 把buf_str作为response返回前端,并设置首部字段
response = make_response(buf_str)
response.headers['Content-Type'] = 'image/gif'
# 将验证码字符串储存在session中
session['image'] = code
return response
def user_login(f):
"""
登录装饰器
"""
@wraps(f)
def decorated_function(*args, **kwargs):
if "user_id" not in session:
return redirect(url_for("home.login"))
return f(*args, **kwargs)
return decorated_function
@home.route("/login/", methods=["GET", "POST"])
def login():
"""
登录
"""
if "user_id" in session: # 如果已经登录,则直接跳转到首页
return redirect(url_for("home.index"))
form = LoginForm() # 实例化LoginForm类
if form.validate_on_submit(): # 如果提交
data = form.data # 接收表单数据
# 判断验证码
if session.get('image').lower() != form.verify_code.data.lower():
flash('验证码错误',"err")
return render_template("home/login.html", form=form) # 返回登录页
# 判断用户名是否存在
user = User.query.filter_by(username=data["username"]).first() # 获取用户信息
if not user :
flash("用户名不存在!", "err") # 输出错误信息
return render_template("home/login.html", form=form) # 返回登录页
# 判断用户名和密码是否匹配
if not user.check_password(data["password"]): # 调用check_password()方法,检测用户名密码是否匹配
flash("密码错误!", "err") # 输出错误信息
return render_template("home/login.html", form=form) # 返回登录页
session["user_id"] = user.id # 将user_id写入session, 后面用户判断用户是否登录
session["username"] = user.username # 将user_id写入session, 后面用户判断用户是否登录
return redirect(url_for("home.index")) # 登录成功,跳转到首页
return render_template("home/login.html",form=form) # 渲染登录页面模板
@home.route("/register/", methods=["GET", "POST"])
def register():
"""
注册功能
"""
if "user_id" in session:
return redirect(url_for("home.index"))
form = RegisterForm() # 导入注册表单
if form.validate_on_submit(): # 提交注册表单
data = form.data # 接收表单数据
# 为User类属性赋值
user = User(
username = data["username"], # 用户名
email = data["email"], # 邮箱
password = generate_password_hash(data["password"]),# 对密码加密
phone = data['phone']
)
db.session.add(user) # 添加数据
db.session.commit() # 提交数据
return redirect(url_for("home.login")) # 登录成功,跳转到首页
return render_template("home/register.html", form=form) # 渲染模板
@home.route("/logout/")
def logout():
"""
退出登录
"""
# 重定向到home模块下的登录。
session.pop("user_id", None)
session.pop("username", None)
return redirect(url_for('home.login'))
@home.route("/modify_password/",methods=["GET","POST"])
@user_login
def modify_password():
"""
修改密码
"""
form = PasswordForm()
if form.validate_on_submit():
data = form.data
user = User.query.filter_by(username=session["username"]).first()
from werkzeug.security import generate_password_hash
user.password = generate_password_hash(data["password"])
db.session.add(user)
db.session.commit()
return "<script>alert('密码修改成功');location.href='/';</script>"
return render_template("home/modify_password.html", form=form)
@home.route("/")
def index():
"""
首页
"""
# 获取2个热门商品
hot_goods = Goods.query.order_by(Goods.views_count.desc()).limit(2).all()
# 获取12个新品
new_goods = Goods.query.filter_by(is_new=1).order_by(
Goods.addtime.desc()
).limit(12).all()
# 获取12个打折商品
sale_goods = Goods.query.filter_by(is_sale=1).order_by(
Goods.addtime.desc()
).limit(12).all()
return render_template('home/index.html',new_goods=new_goods,sale_goods=sale_goods,hot_goods=hot_goods) # 渲染模板
@home.route("/goods_list/<int:supercat_id>/")
def goods_list(supercat_id=None): # supercat_id 为商品大分类ID
"""
商品页
"""
page = request.args.get('page', 1, type=int) # 获取page参数值
page_data = Goods.query.filter_by(supercat_id=supercat_id).paginate(page=page, per_page=12)
hot_goods = Goods.query.filter_by(supercat_id=supercat_id).order_by(Goods.views_count.desc()).limit(7).all()
return render_template('home/goods_list.html',page_data=page_data,hot_goods=hot_goods,supercat_id=supercat_id)
@home.route("/goods_detail/<int:id>/")
def goods_detail(id=None): # id 为商品ID
"""
详情页
"""
user_id = session.get('user_id', 0) # 获取用户ID,判断用户是否登录
goods = Goods.query.get_or_404(id) # 根据景区ID获取景区数据,如果不存在返回404
# 浏览量加1
goods.views_count += 1
db.session.add(goods) # 添加数据
db.session.commit() # 提交数据
# 获取左侧热门商品
hot_goods = Goods.query.filter_by(subcat_id=goods.subcat_id).order_by(Goods.views_count.desc()).limit(5).all()
# 获取底部相关商品
similar_goods = Goods.query.filter_by(subcat_id=goods.subcat_id).order_by(Goods.addtime.desc()).limit(5).all()
return render_template('home/goods_detail.html',goods=goods,hot_goods=hot_goods,similar_goods=similar_goods,user_id=user_id) # 渲染模板
@home.route("/search/")
def goods_search():
"""
搜素功能
"""
page = request.args.get('page', 1, type=int) # 获取page参数值
keywords = request.args.get('keywords','',type=str)
if keywords :
# 使用like实现模糊查询
page_data = Goods.query.filter(Goods.name.like("%"+keywords+"%")).order_by(
Goods.addtime.desc()
).paginate(page=page, per_page=12)
else :
page_data = Goods.query.order_by(
Goods.addtime.desc()
).paginate(page=page, per_page=12)
hot_goods = Goods.query.order_by(Goods.views_count.desc()).limit(7).all()
return render_template("home/goods_search.html", page_data=page_data,keywords=keywords,hot_goods=hot_goods)
@home.route("/cart_add/")
@user_login
def cart_add():
"""
添加购物车
"""
cart = Cart(
goods_id = request.args.get('goods_id'),
number = request.args.get('number'),
user_id=session.get('user_id', 0) # 获取用户ID,判断用户是否登录
)
db.session.add(cart) # 添加数据
db.session.commit() # 提交数据
return redirect(url_for('home.shopping_cart'))
@home.route("/cart_clear/")
@user_login
def cart_clear():
"""
清空购物车
"""
user_id = session.get('user_id', 0) # 获取用户ID,判断用户是否登录
Cart.query.filter_by(user_id=user_id).update({
'user_id': 0})
db.session.commit()
return redirect(url_for('home.shopping_cart'))
@home.route("/shopping_cart/")
@user_login
def shopping_cart():
user_id = session.get('user_id',0)
cart = Cart.query.filter_by(user_id = int(user_id)).order_by(Cart.addtime.desc()).all()
if cart:
return render_template('home/shopping_cart.html',cart=cart)
else:
return render_template('home/empty_cart.html')
@home.route("/cart_order/",methods=['GET','POST'])
@user_login
def cart_order():
if request.method == 'POST':
user_id = session.get('user_id',0) # 获取用户id
# 添加订单
orders = Orders(
user_id = user_id,
recevie_name = request.form.get('recevie_name'),
recevie_tel = request.form.get('recevie_tel'),
recevie_address = request.form.get('recevie_address'),
remark = request.form.get('remark')
)
db.session.add(orders) # 添加数据
db.session.commit() # 提交数据
# 添加订单详情
cart = Cart.query.filter_by(user_id=user_id).all()
object = []
for item in cart :
object.append(
OrdersDetail(
order_id=orders.id,
goods_id=item.goods_id,
number = item.number,)
)
db.session.add_all(object)
# 更改购物车状态
Cart.query.filter_by(user_id=user_id).update({
'user_id': 0})
db.session.commit()
return redirect(url_for('home.index'))
@home.route("/order_list/",methods=['GET','POST'])
@user_login
def order_list():
""""
我的订单
"""
user_id = session.get('user_id',0)
orders = OrdersDetail.query.join(Orders).filter(Orders.user_id==user_id).order_by(Orders.addtime.desc()).all()
return render_template('home/order_list.html',orders=orders)
@home.route("/collect_add/")
@user_login
def collect_add():
"""
收藏景区
"""
scenic_id = request.args.get("scenic_id", "") # 接收传递的参数scenic_id
user_id = session.get('user_id',0) # 获取当前用户的ID
collect = Collect.query.filter_by( # 根据用户ID和景区ID判断是否该收藏
user_id =int(user_id),
scenic_id=int(scenic_id)
).count()
# 已收藏
if collect == 1:
data = dict(ok=0) # 写入字典
# 未收藏进行收藏
if collect == 0:
collect = Collect(
user_id =int(user_id),
scenic_id=int(scenic_id)
)
db.session.add(collect) # 添加数据
db.session.commit() # 提交数据
data = dict(ok=1) # 写入字典
import json # 导入模块
return json.dumps(data) # 返回json数据
@home.route("/collect_cancel/")
@user_login
def collect_cancel():
"""
收藏景区
"""
id = request.args.get("id", "") # 获取景区ID
user_id = session["user_id"] # 获取当前用户ID
collect = Collect.query.filter_by(id=id,user_id=user_id).first() # 查找Collect表,查看记录是否存在
if collect : # 如果存在
db.session.delete(collect) # 删除数据
db.session.commit() # 提交数据
data = dict(ok=1) # 写入字典
else :
data = dict(ok=-1) # 写入字典
import json # 引入json模块
return json.dumps(data) # 输出json格式
@home.route("/collect_list/")
@user_login
def collect_list():
page = request.args.get('page', 1, type=int) # 获取page参数值
# 根据user_id删选Collect表数据
page_data = Collect.query.filter_by(user_id = session['user_id']).order_by(
Collect.addtime.desc()
).paginate(page=page, per_page=3) # 使用分页方法
return render_template('home/collect_list.html',page_data=page_data) # 渲染模板
感兴趣的可以先收藏起来,点赞关注不迷路,想学习更多项目可以查看主页,大家在毕设选题,项目代码以及论文编写等相关问题都可以给我留言咨询,希望可以帮助同学们顺利毕业!
由于篇幅限制,获取完整文章或源码、代做项目的,拉到文章底部即可看到个人联系方式。
点赞、收藏、关注,不迷路,下方查看获取联系方式
文章浏览阅读2w次,点赞7次,收藏51次。四个步骤1.创建C++ Win32项目动态库dll 2.在Win32项目动态库中添加 外部依赖项 lib头文件和lib库3.导出C接口4.c#调用c++动态库开始你的表演...①创建一个空白的解决方案,在解决方案中添加 Visual C++ , Win32 项目空白解决方案的创建:添加Visual C++ , Win32 项目这......_c#调用lib
文章浏览阅读4.6k次。苹方字体是苹果系统上的黑体,挺好看的。注重颜值的网站都会使用,例如知乎:font-family: -apple-system, BlinkMacSystemFont, Helvetica Neue, PingFang SC, Microsoft YaHei, Source Han Sans SC, Noto Sans CJK SC, W..._ubuntu pingfang
文章浏览阅读159次。表单表单概述表单标签表单域按钮控件demo表单标签表单标签基本语法结构<form action="处理数据程序的url地址“ method=”get|post“ name="表单名称”></form><!--action,当提交表单时,向何处发送表单中的数据,地址可以是相对地址也可以是绝对地址--><!--method将表单中的数据传送给服务器处理,get方式直接显示在url地址中,数据可以被缓存,且长度有限制;而post方式数据隐藏传输,_html表单的处理程序有那些
文章浏览阅读1.2k次。使用说明:开启Google的登陆二步验证(即Google Authenticator服务)后用户登陆时需要输入额外由手机客户端生成的一次性密码。实现Google Authenticator功能需要服务器端和客户端的支持。服务器端负责密钥的生成、验证一次性密码是否正确。客户端记录密钥后生成一次性密码。下载谷歌验证类库文件放到项目合适位置(我这边放在项目Vender下面)https://github.com/PHPGangsta/GoogleAuthenticatorPHP代码示例://引入谷_php otp 验证器
文章浏览阅读4.3k次,点赞5次,收藏11次。matplotlib.plot画图横坐标混乱及间隔处理_matplotlib更改横轴间距
文章浏览阅读2.2k次。①Storage driver 处理各镜像层及容器层的处理细节,实现了多层数据的堆叠,为用户 提供了多层数据合并后的统一视图②所有 Storage driver 都使用可堆叠图像层和写时复制(CoW)策略③docker info 命令可查看当系统上的 storage driver主要用于测试目的,不建议用于生成环境。_docker 保存容器
文章浏览阅读834次,点赞27次,收藏13次。网络拓扑结构是指计算机网络中各组件(如计算机、服务器、打印机、路由器、交换机等设备)及其连接线路在物理布局或逻辑构型上的排列形式。这种布局不仅描述了设备间的实际物理连接方式,也决定了数据在网络中流动的路径和方式。不同的网络拓扑结构影响着网络的性能、可靠性、可扩展性及管理维护的难易程度。_网络拓扑csdn
文章浏览阅读1.8k次,点赞5次,收藏8次。IOS系统Date的坑要创建一个指定时间的new Date对象时,通常的做法是:new Date("2020-09-21 11:11:00")这行代码在 PC 端和安卓端都是正常的,而在 iOS 端则会提示 Invalid Date 无效日期。在IOS年月日中间的横岗许换成斜杠,也就是new Date("2020/09/21 11:11:00")通常为了兼容IOS的这个坑,需要做一些额外的特殊处理,笔者在开发的时候经常会忘了兼容IOS系统。所以就想试着重写Date函数,一劳永逸,避免每次ne_date.prototype 将所有 ios
文章浏览阅读5.3k次。方法一:用PLSQL Developer工具。 1 在PLSQL Developer的sql window里输入select * from test for update; 2 按F8执行 3 打开锁, 再按一下加号. 鼠标点到第一列的列头,使全列成选中状态,然后粘贴,最后commit提交即可。(前提..._excel导入pl/sql
文章浏览阅读83次。Git常用命令速查手册1、初始化仓库git init2、将文件添加到仓库git add 文件名 # 将工作区的某个文件添加到暂存区 git add -u # 添加所有被tracked文件中被修改或删除的文件信息到暂存区,不处理untracked的文件git add -A # 添加所有被tracked文件中被修改或删除的文件信息到暂存区,包括untracked的文件...
文章浏览阅读202次。分享119个ASP.NET源码总有一个是你想要的_千博二手车源码v2023 build 1120
文章浏览阅读1.8k次。版权声明:转载请注明出处 http://blog.csdn.net/irean_lau。目录(?)[+]1、缺省构造函数。2、缺省拷贝构造函数。3、 缺省析构函数。4、缺省赋值运算符。5、缺省取址运算符。6、 缺省取址运算符 const。[cpp] view plain copy_空类默认产生哪些类成员函数