一.前言
针对搭伙吃饭的点菜,我们时常会从人数和人均金额去考虑一家餐厅的菜单,所以点菜对于大锅饭的伙伴也成了一门学问和难题,本篇文章巧妙的应用代码思想,将实际问题转化为代码问题,例如如下是一个醉得意的点菜系统的damo。
所以为了实现这些主要点餐功能:
- 提高每天中午点餐效率,把点餐时间由20分钟优化为1分钟;
- 知道在哪些付款金额范围内,可以有哪些菜单可以选择;
- 知道人均付款金额;
- 知道微信需要付款总金额;
- 给餐厅老板发的点餐文案;
- 当前点餐菜单里的具体菜品名和价格;
结合之前学习的知识点,利用django框架的MTV思想,开发一个简单的html页面,让公司同个局域网的同事自己进行操作和查询醉得意菜单并得到想要的数据。
二、相关完整流程的操作步骤
1、第一步,在django项目【helloworld】的根路径【helloworld/】下,手动新增一个空文件【utils】,并把自己写的一个py脚本放到该文件【utils】里面。
细节:
- 工具类默认要放在同个文件夹A,文件夹A由使用人员手动创建;
- 文件夹A名称默认为utils,默认放在项目根目录;(大多数框架和行业人员使用时的默认遵守规范);
2、第二步,单元测试【zuideyiMenu.py】里的类【Zuideyi】代码功能,确保能正常实现。
#!/usr/bin/python
# coding:utf-8
"""
@file: zuideyiMenu.py
@author: lucas
@createTime: 2021/3/2 10:37 上午
@Function: 定义一个醉得意点菜功能菜单类
"""
import random
class Zuideyi:
def __init__(self, total, couponMoney, everyPlanMinimalMoney, everyPlanMaximalMoney):
'''
total: 就餐总人数
couponMoney: 优惠券金额
everyPlanMinimalMoney: 人均最低消费金额
everyPlanMaximalMoney: 人均最高消费金额
'''
self.total = total
self.couponMoney = couponMoney
self.everyPlanMinimalMoney = everyPlanMinimalMoney
self.everyPlanMaximalMoney = everyPlanMaximalMoney
# 自助费= 5元/人 (该属性值暂时固定)
self.supportFee = 5
# 折扣率 = 实际充值金额/最终获得金额 (该属性值暂时固定)
self.discountRate = 1000 / 1120
# 菜品集合(该属性值暂时固定)
self.menu = {
"招牌菜": {"酱椒片片鱼": 68},
"6大必点菜": {"鲜花椒牛肉粒": 58, "梅菜扣肉": 46, "香酥脆皮鸭": 32, "汽锅时蔬": 28, "台式三杯鸡": 42},
"醉经典": {"得意醉排骨": 12, "肉末茄子": 23, "铁板黑椒牛肉": 48, "大碗有机花菜": 22, "肉沫蒸蛋": 18, },
"下饭南方菜": {"农家烧笋干": 32, "海味紫菜煲": 32, "干锅千叶豆腐": 23, "红烧日本豆腐": 23, },
"当季时蔬": {"油淋芥兰": 18, },
"店长推荐": {"闽南醋肉": 36, },
}
# 大菜集合
# self.bigDish = self.menus()[0]
# 小菜集合
# self.sideDish = self.menus()[1]
# # 新增一个空dict,用于存储相关需要展示到前端页面的打印信息
# self.printAll = {}
def total_price_range_of_dishes(self):
'''
return: 可以点的菜品总价区间 = [人均最低消费金额*就餐总人数 / 折扣率 + 优惠券金额,
人均最高消费金额*就餐总人数 / 折扣率 + 优惠券金额]
'''
total_price_range_of_dishes = [self.everyPlanMinimalMoney * self.total / self.discountRate + self.couponMoney,
self.everyPlanMaximalMoney * self.total / self.discountRate + self.couponMoney]
return total_price_range_of_dishes
def menus(self):
'''
return: 返回一个整理过的菜品集合
'''
# 定义单价大于等于30元的菜品为【大菜】,定义单价小于30元的菜品为【小菜】
# 大菜数据集合:bigDish,小菜数据集合:smallDish
bigDish = []
smallDish = []
for key1, value1 in self.menu.items():
for key2, value2 in value1.items():
if value2 >= 30:
bigDish.append({key2: value2})
else:
smallDish.append({key2: value2})
dish = [bigDish, smallDish]
print("大菜集合如下:")
print(bigDish)
print("小菜集合如下:")
print(smallDish)
return dish
def amount_of_payment_of_everyOne(self, totalMoney):
'''
totalMoney: 醉得意点餐菜单总金额(不扣除相关优惠券金额,但包含就餐人数的总自助费)
return: 实际人均需付餐费
'''
amount_of_payment_zuiDeyi = (totalMoney - self.couponMoney)
print("今天醉得意公众号里的会员卡扣款金额:%s" % amount_of_payment_zuiDeyi)
amount_of_payment_weChat = amount_of_payment_zuiDeyi * self.discountRate
print("今天微信实际支付扣款金额:%s" % amount_of_payment_weChat)
amount_of_payment_of_everyOne = amount_of_payment_weChat / self.total
print("今天醉得意可以点的菜品总金额为%s元,点餐人数为:%s人,实际人均需付餐费:%s元" % (totalMoney, self.total, amount_of_payment_of_everyOne))
result1 = {
"今天醉得意公众号里的会员卡扣款金额:": amount_of_payment_zuiDeyi,
"今天微信实际支付扣款金额:": amount_of_payment_weChat,
"今天醉得意可以点的菜品总金额为:": totalMoney,
"今天醉得意点餐人数为:": self.total,
"今天醉得意实际人均需付餐费为:": amount_of_payment_of_everyOne
}
return result1
def chioce(self, bigDishCounts, smallDishCounts):
'''
bigDishCounts: 大菜个数
smallDishCounts: 小菜个数
'''
dish = self.menus()
a1 = random.sample(dish[0], bigDishCounts)
b1 = random.sample(dish[1], smallDishCounts)
# 可以点的点餐菜品
neededMenu = a1 + b1
# 可以点的菜品总金额,初始值为0
totalMoney = 0
# 在微信里要写给醉得意老板的菜单
stringA = ""
for value3 in neededMenu:
for key4, value4 in value3.items():
# print(value4)
totalMoney = totalMoney + value4
stringA = stringA + key4 + ","
stringA = stringA[:-1]
# 总菜单金额 = 总菜品金额+ 总自助费
totalMoney = totalMoney + self.supportFee * self.total
# 判断totalMoney 是否在可消费总金额区间
if self.total_price_range_of_dishes()[0] <= totalMoney <= self.total_price_range_of_dishes()[1]:
result = {
"今天醉得意可以点的点餐菜品:": neededMenu,
"今天醉得意可以点的点餐菜品总数:": bigDishCounts + smallDishCounts,
"今天可以微信里发给醉得意老板的点餐文案:--->老板,今天点餐人数%s,11:45可以陆续上菜,桌上饮料杯子不用放,餐桌号安排好了之后麻烦说一声。点菜菜单如下:" % self.total: stringA,
"今天总消费金额区间:": self.total_price_range_of_dishes()
}
result1 = self.amount_of_payment_of_everyOne(totalMoney)
print(
"======================================================================================================================================")
newResult = dict(result, **result1)
return newResult
else:
return {"error:": "该场景下没有符合要求的醉得意菜单"}
def run(self):
# 当11个人:3个大菜,3个小菜;3个大菜,4个小菜; 3个大菜,5个小菜;3个大菜,6个小菜;3个大菜,7个小菜; 4个大菜,3个小菜;4个大菜,4个小菜; 4个大菜,5个小菜;4个大菜,6个小菜;
# 当10个人:3个大菜,3个小菜;3个大菜,4个小菜; 3个大菜,5个小菜;3个大菜,6个小菜;3个大菜,7个小菜; 4个大菜,3个小菜;4个大菜,4个小菜; 4个大菜,5个小菜;4个大菜,6个小菜;
# 当9个人:3个大菜,3个小菜;3个大菜,4个小菜; 3个大菜,5个小菜;3个大菜,6个小菜; 2个大菜,4个小菜;2个大菜,5个小菜;2个大菜,6个小菜;2个大菜,7个小菜;
# 当8个人:3个大菜,2个小菜;3个大菜,3个小菜;3个大菜,4个小菜; 3个大菜,5个小菜;3个大菜,6个小菜; 2个大菜,3个小菜;2个大菜,4个小菜;2个大菜,5个小菜;2个大菜,6个小菜;
# 当7个人:2个大菜,3个小菜;2个大菜,4个小菜;2个大菜,5个小菜;2个大菜,6个小菜;
# 当6个人:2个大菜,3个小菜;2个大菜,2个小菜;2个大菜,1个小菜; 1个大菜,5个小菜;1个大菜,4个小菜;1个大菜,3个小菜;1个大菜,2个小菜;1个大菜,1个小菜;
if self.total == 10 or 11:
a1 = self.chioce(bigDishCounts=3, smallDishCounts=3)
a2 = self.chioce(bigDishCounts=3, smallDishCounts=4)
a3 = self.chioce(bigDishCounts=3, smallDishCounts=5)
a4 = self.chioce(bigDishCounts=3, smallDishCounts=6)
a5 = self.chioce(bigDishCounts=3, smallDishCounts=7)
a6 = self.chioce(bigDishCounts=4, smallDishCounts=3)
a7 = self.chioce(bigDishCounts=4, smallDishCounts=4)
a8 = self.chioce(bigDishCounts=4, smallDishCounts=5)
a9 = self.chioce(bigDishCounts=4, smallDishCounts=6)
b = [a1, a2, a3, a4, a5, a6, a7, a8, a9]
return {"all": b}
if self.total == 9:
a1 = self.chioce(bigDishCounts=3, smallDishCounts=3)
a2 = self.chioce(bigDishCounts=3, smallDishCounts=4)
a3 = self.chioce(bigDishCounts=3, smallDishCounts=5)
a4 = self.chioce(bigDishCounts=3, smallDishCounts=6)
a5 = self.chioce(bigDishCounts=2, smallDishCounts=4)
a6 = self.chioce(bigDishCounts=2, smallDishCounts=5)
a7 = self.chioce(bigDishCounts=2, smallDishCounts=6)
a8 = self.chioce(bigDishCounts=2, smallDishCounts=7)
b = [a1, a2, a3, a4, a5, a6, a7, a8]
return {"all": b}
if self.total == 8:
a1 = self.chioce(bigDishCounts=3, smallDishCounts=2)
a2 = self.chioce(bigDishCounts=3, smallDishCounts=3)
a3 = self.chioce(bigDishCounts=3, smallDishCounts=4)
a4 = self.chioce(bigDishCounts=3, smallDishCounts=5)
a5 = self.chioce(bigDishCounts=3, smallDishCounts=6)
a6 = self.chioce(bigDishCounts=2, smallDishCounts=3)
a7 = self.chioce(bigDishCounts=2, smallDishCounts=4)
a8 = self.chioce(bigDishCounts=2, smallDishCounts=5)
a9 = self.chioce(bigDishCounts=2, smallDishCounts=6)
a10 = self.chioce(bigDishCounts=2, smallDishCounts=7)
b = [a1, a2, a3, a4, a5, a6, a7, a8, a9, a10]
return {"all": b}
if self.total == 7:
a1 = self.chioce(bigDishCounts=2, smallDishCounts=3)
a2 = self.chioce(bigDishCounts=2, smallDishCounts=4)
a3 = self.chioce(bigDishCounts=2, smallDishCounts=5)
a4 = self.chioce(bigDishCounts=2, smallDishCounts=6)
b = [a1, a2, a3, a4]
return {"all": b}
if self.total == 6:
a1 = self.chioce(bigDishCounts=2, smallDishCounts=3)
a2 = self.chioce(bigDishCounts=2, smallDishCounts=2)
a3 = self.chioce(bigDishCounts=2, smallDishCounts=1)
a4 = self.chioce(bigDishCounts=1, smallDishCounts=5)
a5 = self.chioce(bigDishCounts=1, smallDishCounts=4)
a6 = self.chioce(bigDishCounts=1, smallDishCounts=3)
a7 = self.chioce(bigDishCounts=1, smallDishCounts=2)
a8 = self.chioce(bigDishCounts=1, smallDishCounts=1)
b = [a1, a2, a3, a4, a5, a6, a7, a8]
return {"all": b}
if __name__ == "__main__":
test = Zuideyi(9, 5, 19, 22.5)
test.run()
3、第三步,在指定应用【hello】里的目录【templates】里编写一个【search_form.html】,用于让使用人员输入并提交相关数据。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>醉得意点餐页面</title>
</head>
<body>
<form action="{% url 'search_interface' %}" method="get">
请输入就餐的人数:<input type="text" name="total" placeholder="请输入就餐人数" value="7"/>
<br>
请输入优惠券金额:<input type="text" name="couponMoney" placeholder="请输入优惠券金额" value="5"/>
<br>
人均最低消费金额:<input type="text" name="everyPlanMinimalMoney" placeholder="人均最低消费金额" value="22"/>
<br>
人均最高消费金额:<input type="text" name="everyPlanMaximalMoney" placeholder="人均最高消费金额" value="30"/>
<br>
<br>
<input type="submit" value="开始搜索相关合适的菜单信息"/>
</form>
</body>
</html>
细节:
①.form属性里的action元素的值的赋值含义
./代表当前目录,?代表查询字符串为空
action="" //一般可以为空的,这里的双引号都要有的,表示提单提交给自己(也就是当前页处理)
action="a.php" //是提交给 当前目录的a.php 处理
提交到本目录的默认主页
如果是 action="?" 就是提交给自己
②.form属性里的action元素的值如何赋值的官方解释,可以参考这篇菜鸟教程:
③.action值的使用场景分析
4、第四步,在指定应用【hello】里的目录【templates】里编写一个【zuideyi_result.html】,用于展示查询到的醉得意菜单相关数据。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>符合点餐要求的醉得意</title>
</head>
<body>
{#<h4> {
{views_dict}}</h4>#}
{#<h2> {
{views_dict.b}}</h2>#}
{#<br>==============<br>#}
{##}
{##}
{#<h4> {
{views_dict.all}}</h4>#}
{#<br>==============<br>#}
{##}
{##}
<ul>
<h4> {% for thing in views_dict.all %}
{% for i,j in thing.items %}
{
{ i }}{
{ j }}<br>
{% endfor %}
<br>
========================================
<br>
<br>
{% endfor %}
</h4>
</ul>
</body>
</html>
5、第五步,在指定应用【hello】里的【views.py】里编写一个视图函数/接口【search_form】,用于返回【search_form.html】。
6、第六步,在指定应用【hello】里的【views.py】里编写一个视图函数/接口【search】,用于返回【zuideyi_result.html】。
# 接收请求数据
from utils.zuideyiMenu import Zuideyi
def search(request):
request.encoding = 'utf-8'
# if 'total' in request.GET and request.GET['total']:
# message = '你搜索的内容为: ' + request.GET['total']
# else:
# message = '你提交了空表单'
total = request.GET['total']
couponMoney = request.GET['couponMoney']
everyPlanMinimalMoney = request.GET['everyPlanMinimalMoney']
everyPlanMaximalMoney = request.GET['everyPlanMaximalMoney']
# list = [total, couponMoney, everyPlanMinimalMoney, everyPlanMaximalMoney]
total = int(total)
couponMoney = int(couponMoney)
everyPlanMinimalMoney = float(everyPlanMinimalMoney)
everyPlanMaximalMoney = float(everyPlanMaximalMoney)
zuideyi = Zuideyi(total=total, couponMoney=couponMoney, everyPlanMinimalMoney=everyPlanMinimalMoney,
everyPlanMaximalMoney=everyPlanMaximalMoney)
run = zuideyi.run()
views_dict = run
return render(request, 'zuideyi_result.html', {"views_dict": views_dict})
7、第七步,在django项目【helloworld】里路径为【helloworld/helloworld/urls.py/】里编写两个不同的url匹配规则。
8、第八步,启动django项目【helloworld】服务。
9、第九步,在任一浏览器输入地址【http://127.0.0.1:8000/search-form/】或者地址【http://个人电脑IP:8000/search-form/】,会成功访问到页面名为【醉得意点餐页面】的html页面。
10、第十步,在第九步得到的【醉得意点餐页面】里,点击按钮【开始搜索相关合适的菜单信息】,会成功访问到页面名为【符合点餐要求的醉得意】的html页面,该html页面会展示我们想要的相关内容。