明:本次文章是看了B站上的视频和分享的代码笔记后,自己敲了一遍代码。然后再敲一遍代码的同时写文章梳理逻辑,看不懂的同学可以去看原文章和视频。文章如有雷同,可联系我删除!视频链接:
https://www.bilibili.com/video/BV1pq4y1W7a1?spm_id_from=333.999.0.0
博客目录:
一、基于Django+mysql的点餐系统设计--第一篇(开篇:确认需求功能、数据库设计、程序设计)
二、基于Django+mysql的点餐系统设计--第二篇(搭建工程、前后端调试)
三、基于Django+mysql的点餐系统设计--第三篇(编写后台员工管理页面)
四、基于Django+mysql的点餐系统设计--第四篇(编写后台菜品分类管理功能)
五、基于Django+mysql的点餐系统设计--第五篇(编写后台店铺管理页面)
六、基于Django+mysql的点餐系统设计-第六篇(编写后台菜品管理页面)
本章源码下载地址:https://github.com/hopeSuceess/testorder/tree/testorder_2022051501
写到第六篇简单的增删改查已经都非常熟悉了,这里不做过多阐述,本篇针对以下重点功能进行说明:父页面添加路径、外键、菜品分类浏览页的查看菜品、图片修改(另一种考虑更全面的方式)、商铺和菜品分类的二级联动。
前端父页面添加路径比较简单,但是非常重要。它是菜品管理页面展示的入口,相关示例图和代码如下
外键对于数据表来说是很常见的,怎么将外键展示到页面是一个技术点。前面讲菜品分类管理的时候涉及到外键了,这次菜品管理涉及到店铺、菜品分类两个外键,但是从技术逻辑来说,菜品管理的外键展示和菜品分类管理的展示差不多,具体代码如下:
for vo in list2:
shopDetail = Shop.objects.get(id=vo.shop_id)
vo.shopname = shopDetail.name
categoryDetail = Category.objects.get(id=vo.category_id)
vo.categoryname = categoryDetail.name
菜品分类浏览页的查看菜品:前面在讲菜品分类管理的时候有一个"查看菜品"的功能没有实现。在写完菜品分类管理的代码后可以实现这一功能了。
现在开始实现查看菜品的功能,首先在myadmin/urls.py中添加菜品分类的路由
path('product/category/<int:sid>', product.categoryProduct, name="myadmin_categoryProduct_index"), #菜品分类-查看菜品浏览页
确定完url控制器,开始在views视图中写具体的逻辑,在myadmin/views/product.py中的实现看下图
def categoryProduct(request,sid,pIndex=1):
'''浏览信息'''
list = Product.objects.filter(status__lt=9, category_id=sid)
# smod = Product.objects
# list = smod.filter(status__lt=9)
mywhere = []
# 获取、判断并封装keyword建搜索
kw = request.GET.get("keyword", None)
if kw:
# 查询店铺名称中只要含有关键字就可以
list = list.filter(Q(price__contains=kw) | Q(name__contains=kw))
mywhere.append("keyword=" + kw)
list = list.order_by("id") # 对id排序
# 执行分页处理
pIndex = int(pIndex)
page = Paginator(list, 5) # 以5条每页创建分页对象
maxpages = page.num_pages # 最大页数
# 判断页数是否越界
if pIndex > maxpages:
pIndex = maxpages
if pIndex < 1:
pIndex = 1
list2 = page.page(pIndex) # 当前页数据
plist = page.page_range # 页码数列表
for vo in list2:
shopDetail = Shop.objects.get(id=vo.shop_id)
vo.shopname = shopDetail.name
categoryDetail = Category.objects.get(id=vo.category_id)
vo.categoryname = categoryDetail.name
# 封装信息加载模板输出
context = {"productlist": list2, 'plist': plist, 'pIndex': pIndex, 'maxpages': maxpages, 'mywhere': mywhere}
return render(request, "myadmin/product/categoryProduct.html", context)
写完了views视图层开始写templates展示层,在templates/product目录下写一个categoryProduct.html页面,categoryProduct.html页面的内容如下:
{% extends "myadmin/base.html" %}
{% block main_body %}
<!-- Content Header (Page header) -->
<section class="content-header">
<h1>
菜品信息管理
<small>订餐系统后台管理</small>
</h1>
<ol class="breadcrumb">
<li><a href="#"><i class="fa fa-dashboard"></i> 首页</a></li>
<li class="active">菜品信息管理</li>
</ol>
</section>
<!-- Main content -->
<section class="content container-fluid">
<div class="row">
<div class="col-xs-12">
<div class="box">
<div class="box-header">
<h3 class="box-title"><i class="fa fa-calendar"></i> 菜品信息表</h3>
</div>
<!-- /.box-header -->
<div class="box-body table-responsive no-padding">
<table class="table table-hover">
<tr>
<th>ID</th>
<th>店铺名称</th>
<th>菜品分类</th>
<th>菜品图片</th>
<th>菜品名称</th>
<th>单价</th>
<th width="45">状态</th>
<th>添加时间</th>
</tr>
{% for vo in productlist %}
<tr>
<td>{{ vo.id }}</td>
<td>{{ vo.shopname }}</td>
<td>{{ vo.categoryname }}</td>
<td><img src="/static/uploads/product/{{ vo.cover_pic }}" width="30"/></td>
<td>{{ vo.name }}</td>
<td>{{ vo.price }}</td>
<td >
{% if vo.status == 1 %}
<span style="color:green">正常</span>
{% elif vo.status == 2 %}
<span style="color:red">停售</span>
{% elif vo.status == 9 %}
<span style="color:red">已删除</span>
{% else %}
<span style="color:red">未知状态</span>
{% endif %}
</td>
<td width="10%">{{ vo.create_at|date:'Y-m-d' }}</td>
</tr>
{% endfor %}
</table>
</div>
<!-- /.box-body -->
<div class="box-footer clearfix">
<ul class="pagination pagination-sm no-margin pull-right">
<li><a href="{% url 'myadmin_product_index' pIndex|add:-1 %}?{{ mywhere|join:'&' }}">«</a></li>
{% for p in plist %}
<li {% if pIndex == p %}class="active"{% endif %}><a href="{% url 'myadmin_product_index' p %}?{{ mywhere|join:'&' }}">{{ p }}</a></li>
{% endfor %}
<li><a href="{% url 'myadmin_product_index' pIndex|add:1 %}?{{ mywhere|join:'&' }}">»</a></li>
</ul>
</div>
</div>
<!-- /.box -->
</div>
</div>
</section>
<!-- /.content -->
{% endblock %}
templates展示层也搞定了,现在需要在templates/category/index.html的"查看菜品"标签下放一个路径进行调试了,如下:
<a href="{% url 'myadmin_categoryProduct_index' vo.id %}" class="btn btn-warning btn-xs">
<span class="glyphicon glyphicon-search" aria-hidden="true"></span> 查看菜品</a>
在菜品分类浏览页,点击查看菜品,跳到了菜品详情页:
在上一篇店铺管理中涉及到了图片上传和修改的功能,在本篇继续介绍图片修改(另一种考虑更全面的方式)。在菜品修改时,考虑更全面的代码如下:
#后端代码
def update(request,sid):
try:
# 获取原图片
oldpicname = request.POST['oldpicname']
# 图片的上传处理
myfile = request.FILES.get("cover_pic", None)
if not myfile:
cover_pic = oldpicname
else:
cover_pic = str(time.strftime("%Y%m%d.%H%M%S"))+"."+myfile.name.split('.').pop()
destination = open("./static/uploads/product/"+cover_pic, "wb+")
for chunk in myfile.chunks():
destination.write(chunk)
destination.close()
productList = Product.objects.get(id=sid)
productList.shop_id = request.POST['shop_id']
productList.category_id = request.POST['category_id']
productList.name = request.POST['name']
productList.price = request.POST['price']
productList.cover_pic = request.POST['cover_pic']
productList.update_at = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
productList.save()
context = {'info': '修改成功!'}
# 判断并删除老图片
if myfile:
os.remove("./static/uploads/product/"+oldpicname)
except Exception as err:
print(err)
context = {'info': '添加失败!'}
# 判断并删除新图片
if myfile:
os.remove("./static/uploads/product/"+cover_pic)
return render(request, "myadmin/info.html", context)
templates/myadmin/product/edit.html图片更改的前端代码如下:
......
<input type="hidden" name="oldpicname" value="{{ product.cover_pic }}" />
......
<div class="form-group">
<label for="inputPassword3" class="col-sm-2 control-label">菜品图片:</label>
<div class="col-sm-4">
<input type="file" name="cover_pic" /><br/>
<img src="/static/uploads/product/{{ product.cover_pic }}" width="200"/>
</div>
</div>
......
菜品在新增或修改之前,需要带出来其属于哪个商铺下的哪个菜品分类。本篇在实现菜品新增、修改的功能时,在后端传入商铺信息,前端在解析后端传过来的商品信息时,通过ajax调用相对应的菜品分类信息,商铺和菜品分类的二级联动是本篇非常重要的一个知识点和功能点。
这里以新增菜品为例,阐述商铺和菜品分类的二级联动。myadmin/views/product.py中add函数获取店铺信息并渲染到前端,代码如下:
def add(request):
"""加载信息添加表单"""
# 获取当前所以店铺
slist = Shop.objects.values("id", "name")
context = {"shoplist": slist}
return render(request, "myadmin/product/add.html", context)
templates/myadmin/product/add.html中,店铺标签接收后端传过来的店铺信息,如下:
<div class="col-sm-4">
<select name="shop_id" id="shop_id" onchange="doLoadCategory()" class="form-control select2" style="width: 100%;">
{% for svo in shoplist %}
<option value="{{ svo.id }}">{{ svo.name }}</option>
{% endfor %}
</select>
</div>
在上面的代码中,大家可以看到doLoadCategory函数,没错,店铺级联菜品分类靠的就是doLoadCategory函数。在调用店铺标签时会自动调用doLoadCategory函数,从而实现店铺和菜品分类的同步展示。下边看下doLoadCategory函数的代码实现:
//自定义函数,实现通过店铺id,Ajax加载对应的菜品分类信息
function doLoadCategory(){
//获取选中的id号
var id = $("#shop_id").val();
$("#category_id").empty();
$.ajax({
url: "/myadmin/category/load/"+id,
type: 'get',
data: {},
dataType:'json',
success:function(res){
if(res.data.length<1)
return;
var data = res.data;
var select = $("#category_id")
for(var i=0;i<data.length;i++){
$('<option value="'+data[i].id+'">'+data[i].name+'</option>').appendTo(select)
//select.append('<option value="'+data[i].id+'">'+data[i].name+'</option>');
}
}
});
}
这里说下doLoadCategory函数中的 url: "/myadmin/category/load/"+id, 它对应myadmin/urls.py中的
path('category/load/<int:sid>', category.loadCategory, name="myadmin_category_load"), 该路由通过调用loadCategory函数实现对应店铺下菜品分类的展示。
loadCategory函数实现逻辑如下:
def loadCategory(request,sid):
clist = Category.objects.filter(status__lt=9,shop_id=sid).values("id","name")
# 返回QuerySet对象,使用list强转成对应的菜品分类列表信息
print(clist)
print(list(clist))
return JsonResponse({'data': list(clist)})
最后看下商铺和菜品分类二级联动的效果图:
好了,本篇的重点功能讲完了,下一篇讲一下后台账号管理页面
下时节,上海青打过霜更加甜糯,新米已上市,新做的咸肉也好了,烧咸肉菜饭吧: 红润咸肉、腊肠煸出油脂,搭配打过霜的油绿上海青和新米焖一锅咸肉菜饭,成饭红白绿三色相间,有肉有菜有颜,米香肉香菜清香,色味俱佳,令人胃口大开。
By 慢熊熊
1、米洗净入电饭煲加正常焖饭水量、先泡着;入锅称了一下:米和水一共880克,米与水的比例是1:1.2。
2、咸肉、腊肠洗净,切片;
3、上海青摘洗干净,切块段;姜切片;
4、起锅热油,下姜片炒香; 接着下咸肉、腊肠片,煸香、煸出油脂后关火; 拣出姜片不要; 将炒香的腊肠咸肉铲出; 炒锅内留下煸出的油脂待用。
5、将煸香的咸肉、腊肠铲出放入电饭煲,和第2步的米拌匀,合盖,钦下煮饭键。
6、焖饭程序结束后、不急揭盖;炒锅内的余油加热, 下洗净切好的上海青小段翻炒,撒一点点盐,几克糖,翻炒均匀至青菜变软、断生,不要炒出水! 关火铲出。
7、打开电饭煲,香喷喷。
8、加入并铺平刚才炒过的上海青; 淋1小勺芝麻油在青菜表面,加盖,再次钦下焖饭键,焖5分钟,焖熟青菜。
9、开盖,拌匀锅内肉菜饭。
10、加一勺雪白的猪油、和所有菜饭拌匀;这一勺猪油是咸肉菜饭的点睛,强烈建议加,满满的回忆杀啊! 熬出雪白的猪油可以参看这里:http://www.douguo.com/cookbook/3060854.html
11、盛出,米肉菜香三合一,红绿白相间也很好看啊!开饭!
大米可提供丰富B族维生素;大米具有补中益气、健脾养胃、益精强志、和五脏、通血脉、聪耳明目、止烦、止渴、止泻的功效;米粥具有补脾、和胃、清肺功效。
做菜好吃都有技巧,我的每道菜都有小妙招,大家搜索“豆果”可以直接查看我的菜谱!
喜欢这个食谱记得收藏、关注哦!欢迎在下方留言分享您对这道美食的建议。
、课题简介
在信息技术逐渐渗入到生活各个方面的今天,互联网在我们的生活中扮演着越来越重要的角色。现在信息化技术不仅可以提高我们的工作效率,而且能有效的规避错误风险,节约人力成本。美食行业现如今也越来越利用信息化技术来提高点餐效率和质量,餐厅点餐管理系统现在也越来越被个大中小餐厅加以有效利用。
随着餐饮业的发展,开发一套具有普遍通用意义的餐厅点菜管理系统会受到大部分餐厅的青睐,并且该系统必须具备操作简单,功能齐全,可扩展性好,易于维护等特点。由于系统的可扩展性好,我们很容易在原有的功能上进行扩展新的功能,来为每个客户开发一套符合自己特色的餐厅点菜管理系统。所以开发这样一套具有普遍通用意义的餐厅点菜管理系统是非常有必要的。
餐厅订餐系统不仅可以提高餐厅的档次,也减轻了服务员的工作量,便于餐厅管理后厨出菜,提高了服务效率,有效减少了因为人工点菜而会产生的错误,提高了用户体验和服务质量,也为餐厅减少了很大的人工成本支出。
二、选题依据(来源)、背景及其目的意义
随着信息化建设的发展,社会各个领域都在进行不同程度的信息化建设,餐饮系统也一样。餐饮业的信息化不仅需要将整个餐饮业务通过信息系统进行系统管理,同时需要将整个餐饮业务通过信息系统进行系统管理,同时需要将各种人工服务交由计算机处理,比如点菜和菜单的传送等。截止至2007年底,我国餐饮业经营网点已达到350多万家,就业人员超过1500万人。据国家统计局统计,今年上半年全国餐饮业实现营业额2327.2亿元,比去年同期增加319.9亿元、增长9%,增幅比社会商品零售总额增长多出7.3%,在去年营业额实现4368.9亿元,同比增长16.4%的基础上,继续呈现稳步快速发展的良好势头。
传统的餐饮行业,点餐过程都是由餐厅服务员人工完成的。通常的过程都是这样的,客人进入餐厅后,选择好座位开始点餐,服务员等待客人点餐完成,将客人的点餐内容送到厨房,由厨师下厨做菜。这一过程对于一个很小的餐馆来说没有问题,但是如果餐馆比较大或者人比较多,客人的等待时间就会相对于比较长,而且服务员因为忙,会出错,因而提高订单错误的概率,由此引发顾客的不满和投诉,造成客户的流失,也会造成餐厅服务质量的下降,进一步就会危及企业的声誉,造成不可估量的损失。随着移动点餐的技术进步和加强,某些规模比较大的餐饮企业,已经运用更先进的点餐系统,建立一个便捷、高效的餐饮管理系统,以便于更加便捷的优化管理细节,使餐饮业的服务和管理质量提升一个质的飞跃,行业竞争力和品牌形象得到显著提升。
随着市场法规的进一步建立和健全,在激烈竞争中的中国餐饮市场将会得到进一步规划和净化。中国现有的数家餐饮企业和近5000亿的营业额将会不断增加,中国餐饮市场潜力巨大。今后餐饮业将继续保持较快的发展势头,行业规模不断扩大。同时,市场竞争也将更加激烈,市场细分化的趋势使企业特色与个性化更加明显,竞争焦点将更集中地表现在创新能力、经营手段、管理水平与人才保证等方面。
激烈竞争的局面仍将维持,通过竞争将继续对现有的餐饮网点进行优胜略汰,市场的调剂与配置作用更加充分,对企业进一步进行整合与调整,不断推动行业的持续发展。创新经营、品牌营销的力度加强,在行业由品种向品牌、数量向质量、单店经营向规模经营的方向转化中,企业要在市场中占据一定的地位必须加强创新经营力度和文化品牌内涵,进一步突出个性化经营,加强创新、树立品牌、注重营销是广大企业面临的重要课题。传统餐饮向现代餐饮的转化步伐加快,传统餐饮的手工随意性生产、单店作坊式经营、人为经验型管理为主的表现特征,随着餐饮市场需求的不断扩大和社会化、国际化、工业化与产业化的推进,在继承传统饮食文化与烹饪技艺的基础上,以快餐为代表的大众餐饮逐步向标准化操作、工厂化生产,连锁规模化经营和现代科学化管理的目标迈进,不断加快现代餐饮的步伐!
三、国内外对本课题的研究现状
在国内研究中,以餐厅点餐系统为主要研究方向,但早期的系统如点菜宝,电子菜谱等都不太成熟。它们只能显示菜品的图片与价格。简而言之,这些点餐软件只是将传统的纸质菜单显示换成了电子屏显示,并不具备支付、预约功能,没有给传统的点菜过程带来太多的变革,也没有为餐厅的管理带来显著提高,而顾客的实际体验也没有得到太大的改善。随着技术的进步,点餐系统的功能也得到了进一步的完善。通过菜单不仅能看到丰富的菜品样式,还能了解到菜品的原材料。这种方式以顾客为中心,大大地提升了用户体验,还降低了餐厅的人力成本。在研究医院点餐系统中,东南大学附属中医院引进了移动点餐系统,用于病原膳食管理,取得了良好的社会反向和经济效益(朱永坚.2015)。还有少部分的研究是校园点餐系统,其中高应波在文章中提出系统应当采用C/S结构,并从服务器的稳定、可靠性,响应速度,界面的美观程度和易维护性这四个方面进行阐述(高应波.2016)。
除了研究系统,有的学者研究食堂服务质量,通过有效性、可靠性、响应性、保障性这四个维度设计问卷,得出了满意度和消费额之间存在的关系、不同年纪的学生对食堂服务的满意度也不尽相同等结论。有的学者对如何提高食堂服务质量提出了自己的看法,通过足够的沟通机制来提高真实瞬间的服务质量,如:建立食堂经理工作台,随时保持着跟学生们的沟通和交流。
点餐系统从2004年开始出现相关研究,2014年达到最热,却以餐厅点餐系统为主。在近几年中,也出现了对高校食堂点餐系统的研究与开发。但由于软件开发难度大,开发周期长等特点,并没有得到很好的推广与运用。在功能上只是将必备的功能设计出来,并没有针对单一用户进行个性化地推荐菜单或分析饮食健康问题。所以,一款易开发、易使用并能分析师生饮食健康的高校点餐系统将变得不可替代。而目前现有的对高效学生食堂的研究不单单针对学生食堂存在的问题,如日常管理、成本核算等(高庆.2012)。近年来,食品安全渐渐走入大众的视野之中。随着经济水平的提升,越来越多的人已经摆脱了最基本的物质需要,更加注重膳食的营养、合理性。而高校餐饮的消费人群有其特殊性,使其在这样的行业竞争中颇感压力,积极投身改革的浪潮,不断提升服务水平和质量(梁传红.2015)
研究方案:
本文结合餐饮业背景,在对国内外研究现状进行剖析的同时,分析了其中存在的问题和潜在需求,指出餐厅点餐系统的优势。
根据上述思想,本文设计餐厅点餐系统,实现集餐厅点餐与餐厅管理与一体的点餐系统,实现了餐饮业信息化管理,从而加快了餐饮业信息化技术的完善,实现了餐饮业信息化与实践的有效结合。本餐饮系统实现点菜功能,并通过局域网将点菜信息实时传输至后台系统,实现点菜单的实时传送,并能够传送到相应的厨房打印机,并且可以修改菜单,进行退菜、加菜等操作。同时实现餐饮系统的各类信息维护和数据统计。阐述系统的结构、功能以及实现方法,并提出进一步研究的内容。
技术实现方案:
首先使用HTML加CSS来构成前端页面(及Template)。使用Javascript来进行人机交互。用Ajax来进行页面和服务器之间数据的异步传输,使用Django的MVC模式中的M来对数据库进行操作。再使用V来将生成的结果显示在HTML中,在M和V之间需要使用C来处理业务逻辑与model和view交互,返回结果。
Django是高水准的Python编程语言驱动的一个开源模型,控制器风格的Web应用程序框架,它起源于开源社区。使用这种架构,程序员可以方便、快捷地创建高品质、易维护、数据库驱动的应用程序。这也正是OpenStack的Horizon组件采用这种架构进行设计的主要原因。另外,在Django框架中,还包含许多功能强大的第三方插件,使得Django具有较强的可扩展性。Django项目源自一个在线新闻Web站点,于 2005年以开源的形式被释放出来。
Django是用python语言写的开源web开发框架(open source web framework),它鼓励快速开发,并遵循MVC设计。Django遵守BSD版权,初次发布于2005年7月, 并于2008年9月发布了第一个正式版本1.0 。
Django 根据比利时的爵士音乐家Django Reinhardt命名,他是一个吉普赛人,主要以演奏吉它为主,还演奏过小提琴等。由于Django在近年来的迅速发展,应用越来越广泛,被著名IT开发杂志SD Times评选为2013 SD Times 100,位列“API、库和框架”分类第6位,被认为是该领域的佼佼者。
本系统对于用户仅需一台装有浏览器的计算机,即可完成大多数操作,对用户个人电脑本身没有特殊要求,一般当前个人电脑即可满足要求。主要采用了Django框架。对于餐饮点餐系统十分的快捷和便利。用户利用这些开源软件丰富的解决方案可以快速开发系统。
酒店点餐系统,是以方便、简单、直观为前提所开发的,将我们所需要的各项菜品以及用户选项结合到系统中去,让我们的工作信息化,智能化,高效化,取代原有的纸质菜单点餐环节,目前,很多大型餐饮企业,都已经使用自己的点餐系统,通过这些,大大提高了酒店的服务效率。但是时代在发展,酒店系统也会越来越完善,现在的点餐系统,当然不能满足公司的需求,因此,这就推动了酒店点餐系统的进一步优化升级与再次开发。
酒店点餐系统的前端是由HTML加CSS主要构成的,与后端进行交互,使用的是Django框架,使用的数据库是Mysql。主要的内容:菜品信息管理、会员信息管理、大堂点餐管理,以及大堂店铺菜品展出和点餐购物车等。
已经具备的条件
对于Python中Django框架有了详细的学习,以及Django对Mysql有了熟练的掌握,软硬件的兼容问题的解决,同时在网络上也可以查阅大量的资料。
未具备的条件及提出的解决方案
要实现菜单的数据库部分,是根据各种收集得来的数据,需要收集大部分的图片信息。
七、主要参考文献:
[1] 陈承欢.HTML5+CSS3网页设计与制作使用教程.人民邮电出版社.2018
[2] 宋美玲,陈书理.CSS3和HTML5的优势及其在网页布局中的应用.开封大学学报.2017
[3] 钱彬.Python Web开发从入门到实战(Django+Boot).清华大学出版社.2020
[4] 张晓.Django实战Python Web典型模块与项目开发.人民邮电出版社.2020
[5] 朱永坚.移动点餐系统在医院食堂信息化建设中的应用.信息技术与信息化.2015
[6] 高应波.基于C/S结构的校园食堂智能点餐系统的研究.湖北科技学院学报.2016
[7] 高庆.基于饮食生活型态的大学生餐饮消费市场细分研究.论坛与信息论坛.2012
[8] 梁传红.浅析新疆高效餐饮品牌建设.考试周刊.2015
*请认真填写需求信息,我们会在24小时内与您取得联系。