Python Django:如何建立食堂菜单预订系统以避免同时发生预订?

Python Django:如何建立食堂菜单预订系统以避免同时发生预订?,python,django,database,model,webserver,Python,Django,Database,Model,Webserver,所以基本上我是在为食堂创建一个信息亭应用程序的项目中 通常,这是我想要的kiosk应用程序的流程: 用户选择食物/饮料 用户输入他的表号 信息亭检查用户的食品/饮料库存。如果可用,请继续,否则请取消 由于物品有限(例如,仅50件),信息亭会预订物品,以防止其他信息亭应用程序订购该物品。预订将在某个时间到期。(例如,用户忘记带借记卡,因此他将离开信息亭) 用户付款 信息亭将订单发布到web服务器。在付款成功之前,订单不会发布到web服务器(可能会失败) 命令完成了。售货亭打印收据 这是我目前的型号

所以基本上我是在为食堂创建一个信息亭应用程序的项目中

通常,这是我想要的kiosk应用程序的流程:

  • 用户选择食物/饮料
  • 用户输入他的表号
  • 信息亭检查用户的食品/饮料库存。如果可用,请继续,否则请取消
  • 由于物品有限(例如,仅50件),信息亭会预订物品,以防止其他信息亭应用程序订购该物品。预订将在某个时间到期。(例如,用户忘记带借记卡,因此他将离开信息亭)
  • 用户付款
  • 信息亭将订单发布到web服务器。在付款成功之前,订单不会发布到web服务器(可能会失败)
  • 命令完成了。售货亭打印收据
  • 这是我目前的型号:

    菜单项

    类菜单(models.Model):
    image=models.ImageField(上传到=路径并重命名)
    name=models.CharField(最大长度=100)
    price=models.IntegerField()
    category=models.IntegerField()//食物或饮料
    可用性=models.BooleanField(默认值=False)
    qty=models.IntegerField(默认值=100)//售完时将达到0。
    sellerID=models.ForeignKey(卖方,on_delete=models.PROTECT)
    
    命令

    类顺序(models.Model):
    cardID=models.IntegerField()
    amount=models.IntegerField()
    time=models.DateTimeField(auto\u now\u add=True)
    
    订单详情

    类OrderDetail(models.Model):
    orderID=models.ForeignKey(订单,on_delete=models.PROTECT)
    menuID=models.ForeignKey(菜单,on_delete=models.PROTECT)
    price=models.IntegerField()
    数量=型号。整型字段()
    tableNumber=models.IntegerField()
    done=models.BooleanField(默认值=False)
    finishTime=models.DateTimeField(null=True,blank=True)
    sellerID=models.ForeignKey(卖方,on_delete=models.PROTECT)
    
    有关Web服务器的完整代码,请访问我的github:

    为什么我需要预订系统?因为在付款之前,用户必须确保他会收到订单(不是缺货)。食堂里有不止一台售货机。不要让别人的食物/饮料储存在另一台机器上

    因此,我不知道如何构建预订部分。我不知道如何使预订在某个时间到期。如果没有,是否有其他方法可以防止我在上一段中提到的问题


    我认为这与机票预订系统类似。例如,只剩下一张票了。约翰预定了那次航班,然后约翰将有一定的时间付款。约翰付款后,约翰将得到票。但是当有另一个人的时候,让我们说Alex。亚历克斯试图预订那趟航班,但由于约翰已经预订了,亚历克斯无法预订。(在Alex的屏幕中,该票已售出)。

    您可以在创建并订购包含该项的菜单项后,将菜单项的“availability”布尔字段设置为false(或为此添加一个新的布尔字段,例如“reserved”)。工作流程将是,例如:

    • 创建订单
    • 将项目可用性设置为false
    • 运行单独的线程以监视订单是否已完成
    • 完成订单(或不完成)
    • 当预订线程时间到期且订单尚未完成时,将菜单项的可用性值设置为true,以便再次订购
    示例视图.py

    import threading
    import time
    
    def order_check(order_detail):
        time.sleep(1000)  # waiting time before checking the order;
        if not order_detail.done:
            order_detail.menu.availability = True
            order_detail.menu.save()
    
    def reserve_order_view(request, order_detail_pk):
        order_detail = OrderDetail.objects.get(pk=order_detail_pk)
        order_detail.menu.availability = False
        order_detail.menu.save()
        process_order_thread = threading.Thread(target=order_check, args=(order_detail, ))
        process_order_thread.start()  # start your monitoring thread and continue;
    
    def complete_order_view(request, order_detail_pk):
        order_detail = OrderDetail.objects.get(pk=order_detail_pk)
        order_detail.done = True
        order_detail.save()
        # ... etc...
    
    编辑:根据数量保留

    在这种情况下,您可以根据菜单项的数量编号保留菜单项,只需稍微调整以下方法:

    def order_check(order_detail, item_qty_ordered):
        time.sleep(1000)  # waiting time before checking the order;
        if not order_detail.done:
            order_detail.menu.qty += item_qty_ordered # the order wasn't completed, so add back the menu item quantity;
            order_detail.menu.save()
    
    def reserve_order_view(request, order_detail_pk, item_qty_ordered=1):
        order_detail = OrderDetail.objects.get(pk=order_detail_pk)
        order_detail.menu.qty -= item_qty_ordered # the user is ordering some quantity of the menu item;
        order_detail.menu.save()
        process_order_thread = threading.Thread(target=order_check, kwargs={'order_detail_pk': order_detail_pk, 'item_qty_ordered': item_qty_ordered})
        process_order_thread.start()  # start your monitoring thread and continue;
    

    这只是为了说明工作流程。在您的方法中,您还应该检查并阻止无法使用的菜单项的顺序(数量=0)。

    谢谢您的回答。因此,这种方法将阻止菜单项,对吗?例如,有一个数量为2的热狗。用户是Alex和John。所以基本上如果Alex点了一个热狗(数量=1),那么John不能在Alex完成订单和付款之前点热狗(数量=1)?实际上,我只是想做一个系统,让Alex和John可以点一个热狗。当他们付款时,其他试图订购热狗的人将被拒绝,因为热狗数量为0(由Alex和John保留)。这是有道理的。我已经更新了我的答案,考虑基于数量保留菜单项。让我知道它是否适合你。好的,我明白你的想法。所以我们从不删除失败预订的数据(不付款)?顺便说一句,对于订单详细信息,我会将其作为批量(列表)进行POST请求,那么我如何修改您的代码)?您可以根据需要删除订单详细信息,例如,在时间到期且订单尚未完成后(仅当您不想拥有过去订单的历史记录时),可以在
    order\u check
    方法中删除订单详细信息。至于您的POST请求,请澄清您在请求中包含的数据以及view方法接收的参数,以便我可以编辑代码。@ShalahuddinAl Ayyubbi您的POST数据是一个包含所有所需数据的字典列表,因此您可以循环查看它并查询订单详细信息,例如,对于request.data中的数据dict.data:order\u detail=OrderDetail.objects.get(id=int(data\u dict['orderID'))。除此之外,我的回答已经解释过了。