点击小眼睛开启蜘蛛网特效

django小项目:搭建简易火车车票预订系统

图片挂掉了,请看我之前的博客:https://blog.csdn.net/IAMoldpan/article/details/78820740

简易车票预订系统

简单的车票预订系统,采用django2.0搭建。

实现的功能:

  • 预订功能:该系统使用户能够预订两天之内(今明两天)的车票,23点之后(不包含)不能预订当天的车票;
  • 信息反馈:用户输入车票日期,若不在两天之内,返回“不在预订日期内”信息,提示用户重新输入车票日期,若在两天之内,输入乘车时间(整点发车,每车100人,一人一座一票),如果没有空余的座位,返回“暂无座位”,若有空余的座位,提示用户输入姓名和手机号码,若姓名不为空且手机号码为 11 位有效号码并且此号码没有预定过此时间车票,则提示“**客户,恭喜您订票成功”,服务器端将姓名和手机号码存起来作为预订信息,否则,提醒用户“姓名为空或手机号码无效,请您重新输入”;
  • 查询功能:用户输入姓名、手机号码,若姓名正确且为 11 位有效号码并且此号码订过车票,则提供用户该车票的发车时间;
  • 退订功能:向用户确定是否退订,如果用户确认退订,则在服务器端将此姓名和号码的订票信息删除,并返回“退订成功”,如果用户不确认,则返回“取消退订”;若姓名、手机号码不正确或不存在于服务器,则返回“无效姓名或无效号码”,再次提示用户输入姓名和手机号码。

界面展示

《django小项目:搭建简易火车车票预订系统》

简单的购票界面,使用html、css和bootstrap搭建。所有操作都在“一个”页面内完成,通过此页面可以进行预订车票、查询所购买的车票以及取消预订的车票。

Model部分

使用的数据库为mysql。

"""
订票系统-数据库类型定义部分
使用数据库 mysql
--------------------------------
定义数据类型:1、订票类型 2、会员类型
"""

from django.db import models
from datetime import datetime


class Tickets(models.Model):
    name = models.CharField(max_length=30, verbose_name=u"车票名称")
    num = models.CharField(default='K100', max_length=10, verbose_name=u"车票编号")
    time = models.DateTimeField(verbose_name=u"车票出发时间")
    brief = models.TextField(max_length=300, verbose_name=u"车票信息")
    seats = models.IntegerField(default=0, verbose_name=u"剩余座位")

    def __str__(self):
        return self.name

    class Meta:
        verbose_name = "车票信息"
        verbose_name_plural = verbose_name


class Person(models.Model):
    name = models.CharField(max_length=10, verbose_name=u"乘客名称")
    phone_number = models.CharField(max_length=11, verbose_name=u"电话号码")
    ticket_name = models.CharField(default=' ', max_length=30, verbose_name=u"购买车票名称") # 实际存储为车次,非车票名称
    ticket_time = models.DateTimeField(default=datetime.now(), verbose_name=u"购买车票时间")

    def __str__(self):
        return self.name

    class Meta:
        verbose_name = "乘客信息"
        verbose_name_plural = verbose_name

表单Form部分

分别对应页面中两个输入表单。

"""
订票系统-表单处理部分
--------------------------------
"""

from django import forms
from .models import Person


# 预订车票填写信息Form
class TicketForm(forms.Form):

    name = forms.CharField(label='name', max_length=10, error_messages={'required': '请填写您的姓名',
                                                                        'max_length': '名字太长了'})
    phone_number = forms.CharField(label='phone_number', min_length=11, max_length=11,
                                   error_messages={'required': '手机号码输入不正确',
                                                   'min_length': '您输入的号码数不符合11位',
                                                   'max_length': '您输入的号码数不符合11位'})
    ticket_num = forms.CharField(label='ticket_num', max_length=10, error_messages={'required': '车票编号输入不正确'})
    # 因为预订车票车次已经足够,车票时间有些多余,所以删掉
    # ticket_time = forms.DateTimeField(label='ticket_time', error_messages={'required': '车票时间输入不正确'})


# 查询信息填写Form
class PersonForm(forms.Form):
    name = forms.CharField(label='name', max_length=10, error_messages={'required': '请填写您的姓名',
                                                                        'max_length': '名字太长了'})
    phone_number = forms.CharField(label='phone_number', min_length=11, max_length=11,
                                   error_messages={'required': '请输入手机号码',
                                                   'min_length': '您输入的号码数不符合11位',
                                                   'max_length': '您输入的号码数不符合11位'})

View部分

需要注意此view在一个静态页面中进行操作,同一个页面中有三个表单。

"""
订票系统-视图逻辑定义部分
分别包括:信息显示view、预订车票view以及查询取消view
--------------------------------
"""

from django.shortcuts import render, redirect
from apps.order.models import Person, Tickets
from django.views import View
from .forms import TicketForm, PersonForm
from django.http import HttpResponseRedirect
from django.urls import reverse
from datetime import datetime


# 首页显示信息view,将所有的信息传递给主页并进行显示
def detailview(request):
    # 获取数据库中所有的信息
    tickets = Tickets.objects.all()
    persons = Person.objects.all()
    ticket_form = TicketForm()
    person_form = PersonForm()
    # 打包为dic
    content = {
        'tickets': tickets,
        'persons': persons,
        'ticket_form': ticket_form,
        'person_form': person_form,
    }
    return render(request, 'order_system.html', context=content)


# 预订车票功能view
def orderview(request):
    # 页面中有信息传递进来,此时method==POST
    if request.method == 'POST':
        # 将获取的信息进行Form处理
        ticket_form = TicketForm(request.POST)
        tickets = Tickets.objects.all()
        persons = Person.objects.all()
        person_form = PersonForm()

        content = {
            'tickets': tickets,
            'persons': persons,
            'ticket_form': ticket_form,
            'person_form': person_form,
            'order_message': ''
        }
        # 判断post过来的信息是否正确
        if ticket_form.is_valid():

            ticket = Tickets.objects.get(num=request.POST['ticket_num'])
            # 判断数据库中保存的购票记录中是否存在此人,如果存在则取出该数据赋给person,不存在则新建一个person
            person = Person.objects.create() if not Person.objects.filter(name=request.POST['name']) \
                else Person.objects.get(name=request.POST['name'])
            # 判断购票时间是否正确
            now_time = datetime.now()
            time_day = now_time.day - ticket.time.day

            if person.ticket_name == ticket.num:
                 message = '您已购买过此车票!'
            else:
                if time_day > 1:
                    message = '只能购买今天和明天的车票!'
                else:
                    if time_day == 0 and now_time.hour >= 23:
                        message = '当天车票超过晚上11点不可以进行购买'
                    else:
                        if ticket.seats >= 1:
                            message = '预订成功!'
                            ticket.seats -= 1
                            ticket.save()
                            person.name = request.POST['name']
                            person.phone_number = request.POST['phone_number']
                            person.ticket_time = ticket.time
                            person.ticket_name = request.POST['ticket_num']
                            person.save()
                        else:
                            message = '该车次暂无座位!'
                            person.delete()

            content['order_message'] = message

        return render(request, 'order_system.html', context=content)

    else:

        return HttpResponseRedirect(reverse(detailview))



# 查询订单、删除订单操作view
# 此view与之前的view不同,为class view
# 使用class view中的类变量进行表单间信息的传递
class QueryView(View):
    # 此处定义一个类变量,类变量的内存只存在一份,在所有类实例中会共享此参数
    temp = None

    def get(self,request):
        # get操作返回主页即可
        return HttpResponseRedirect(reverse(detailview))

    def post(self,request):
        if request.POST.get('submit') == 'find':

            person_form = PersonForm(request.POST)
            ticket_form = TicketForm()
            tickets = Tickets.objects.all()
            persons = Person.objects.all()

            content = {
                'tickets': tickets,
                'persons': persons,
                'ticket_form': ticket_form,
                'person_form': person_form,
                'query_message': '',
                'show': 0,
            }

            if person_form.is_valid():

                if Person.objects.filter(name=request.POST['name']):
                    # 根据传递来的post信息,过滤获得此person
                    persons = Person.objects.filter(name=request.POST['name'])
                    content['show'] = 1       # flag,若为1则在页面中显示已经查询到的信息
                    content['persons'] = persons
                    content['query_message'] = '查询成功!'
                    # 将查询信息保存到类变量中
                    QueryView.temp = request.POST['name']
                    return render(request, 'order_system.html', context=content)

                else:
                    content['query_message'] = '用户信息不存在!'
                    return render(request, 'order_system.html', context=content)

            return render(request, 'order_system.html', context=content)

        else:
            if request.POST.get('submit') == 'yes':
                # 从类变量中获取到之前传过来的查询到用户的信息
                persons = Person.objects.get(name=QueryView.temp)
                person_form = PersonForm()
                ticket_form = TicketForm()
                tickets = Tickets.objects.all()
                message = '用户订单取消成功!'

                content = {
                    'tickets': tickets,
                    'persons': persons,
                    'ticket_form': ticket_form,
                    'person_form': person_form,
                    'cansel_message': message,
                }
                # 取消订单后
                ticket = Tickets.objects.get(num=persons.ticket_name)
                ticket.seats += 1 # 座位归还
                ticket.save()
                persons.delete()  # 删除此人购买信息
                return render(request, 'order_system.html', context=content)

            else:

                return HttpResponseRedirect(reverse(detailview))


url部分

from django.contrib import admin
from django.urls import path
from apps.order import views
from apps.order.views import QueryView

urlpatterns = [
    path('admin/', admin.site.urls),
    path('', views.detailview, name='home'),   # 主页url
    path('order/', views.orderview, name='order'),  # 预订url
    path('query/', QueryView.as_view(), name='query'), # 查询取消订单url
    # path('unsubscribe/(?P<user>\w+)/$', views.unsubview, name='unsubscribe')
]

主页html文件

<!DOCTYPE html>
<html lang="zh-Hans">


<head>
    <title>订票页面</title>
        <!-- meta -->
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">

    <!-- css -->
    <link rel="stylesheet" href="https://cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap.min.css">

    <!-- js -->
    <script src="https://cdn.bootcss.com/jquery/3.2.1/jquery.min.js"></script>
    <script src="https://cdn.bootcss.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
</head>
<body>

<div class="container">
    <div class="jumbotron">
        <h1 style="text-align: center">车票预订系统</h1>
        <p style="text-align: center">这是一个简易的车票预订系统,制作者:OLDPAN</p>
    </div>

    <h3 style="text-align: center">当前车票信息</h3>

    <table class="table table-bordered">
        <thead>
        <tr>
            <th>车票编号</th>
            <th>车票名称</th>
            <th>开车时间</th>
            <th>剩余座位</th>
        </tr>
        </thead>
        <tbody>
        {% for ticket in tickets %}
        <tr>
            <td>{{ ticket.num }}</td>
            <td>{{ ticket.name }}</td>
            <td>{{ ticket.time|date:"Y-m-d H:i" }}</td>
            <td>{{ ticket.seats }}</td>
        </tr>
        {% endfor %}
        </tbody>
    </table>

    <h2 style="text-align: center">输入购票信息开始购票</h2>

    <form action="{% url 'order' %}" method="post" >
          {% csrf_token %}
        <div class="form-group">
            <div class="col-xs-2">
                <label for="ticket_num">车票编号</label>
                {{ ticket_form.ticket_num }}
{#                <input class="form-control">#}
                {% for error in ticket_form.ticket_num.errors %}
                     <h6 style="color: red"><strong>{{ error|escape }}</strong></h6>
                {% endfor %}
            </div>
{#        已经有车票编号可供查询预订,所以车票时间有些累赘,故删除#}
{#            <div class="col-xs-2">#}
{#                <label for="ticket_time">乘车时间</label>#}
{#                {{ ticket_form.ticket_time }}#}
{#                <input class="form-control">#}
{#                {% for error in ticket_form.ticket_time.errors %}#}
{#                     <h6 style="color: red"><strong>{{ error|escape }}</strong></h6>#}
{#                {% endfor %}#}
{#            </div>#}
            <div class="col-xs-2">
                <label for="name">用户姓名</label>
                {{ ticket_form.name }}
{#                <input class="form-control">#}
                {% for error in ticket_form.name.errors %}
                     <h6 style="color: red"><strong>{{ error|escape }}</strong></h6>
                {% endfor %}
            </div>
            <div class="col-xs-2">
                <label for="phone_number">手机号</label>
                {{ ticket_form.phone_number }}
{#                <input class="form-control" >#}
                {% for error in ticket_form.phone_number.errors %}
                     <h6 style="color: red"><strong>{{ error|escape }}</strong></h6>
                {% endfor %}
            </div>
            <div class="col-xs-2">
                <br>
                <button type="submit" name="order" class="btn btn-default">购买</button>
                <h6 style="color: red"><strong>{{ order_message }}</strong></h6>
            </div>
        </div>
    </form>

    <br><br><br><br>
    <h2 style="text-align: center">预订信息查询</h2>
    <h5 style="text-align: center">查询结果在下方列表栏中</h5>

    <form action="{% url 'query' %}" method="post" >
          {% csrf_token %}
        <div class="form-group">
            <div class="col-xs-2">
                <label for="name">姓名</label>
                 {{ person_form.name }}
                 {% for error in person_form.name.errors %}
                     <h6 style="color: red"><strong>{{ error|escape }}</strong></h6>
                 {% endfor %}
{#                 {{ person_form.name.errors|escape  }}#}
            </div>
            <div class="col-xs-2">
                <label for="phone_number">电话号码</label>
                {{ person_form.phone_number }}
                {% for error in person_form.phone_number.errors %}
                    <h6 style="color: red"><strong>{{ error|escape }}</strong></h6>
                {% endfor %}
{#                 {{ person_form.phone_number.errors|escape }}#}
            </div>
            <div class="col-xs-2">
                <br>
                <button type="submit" name="submit" value="find" class="btn btn-default">查询</button>
            </div>
            <div class="col-xs-2">
                <br>
                <h6 style="color: red">{{ query_message }}{{ cansel_message }}</h6>
            </div>
        </div>
    </form>

    <br><br><br><br>
    <table class="table table-bordered">
        <thead>
        <tr>
            <th>乘客姓名</th>
            <th>电话号码</th>
            <th>车次</th>
            <th>开车时间</th>
        </tr>
        </thead>
        <tbody>
        {% if show %}
        {% for person in persons %}
        <tr>
            <td>{{ person.name }}</td>
            <td>{{ person.phone_number }}</td>
            <td>{{ person.ticket_name }}</td>
            <td>{{ person.ticket_time|date:"Y-m-d H:i" }}</td>
        </tr>
        {% empty %}
         <tr>
            <td>暂无乘车人</td>
            <td>None</td>
            <td>None</td>
            <td>None</td>
         </tr>
        {% endfor %}
        {% endif %}
        </tbody>
    </table>

    {% if show %}
    <form action="{% url 'query'  %}" method="post" >
          {% csrf_token %}
        <div class="form-group">
            <div class="col-xs-3">
                <h5>您可以取消此订单,确定要取消吗?</h5>
            </div>
            <div class="col-xs-1">
                <button type="submit" name="submit" value="yes" class="btn btn-default">确定取消</button>
            </div>
            <div class="col-xs-1">
                <button type="submit" name="submit" value="no" class="btn btn-default">放弃操作</button>
            </div>
{#            <div class="col-xs-2">#}
{#                <h6 style="color: red">{{ cansel_message }}</h6>#}
{#            </div>#}
        </div>
    </form>
    {% endif %}

</div>

</body>
</html>

相关操作截图

《django小项目:搭建简易火车车票预订系统》

购票预订成功

《django小项目:搭建简易火车车票预订系统》

购票信息查询

《django小项目:搭建简易火车车票预订系统》

点击确定取消取消用户订单

《django小项目:搭建简易火车车票预订系统》

此刻再进行查询查询不到

《django小项目:搭建简易火车车票预订系统》

购买车票日期不对对进行提醒(此时系统时间12-16)

《django小项目:搭建简易火车车票预订系统》

表单中输入信息不正确是进行提示。

后记

本来是女朋友的大作业,做这个小系统花了差不多两天的功夫,之前使用django搭过博客,这次做这个小东西,回顾之余也遇到了几个小问题,如何在同一个页面中进行不同表单间信息的传递?如果判断同一个页面中不同表单的执行动作?花费了一些功夫终于弄了出来。希望对大家有帮助。

源代码被我上传到了github,有兴趣参考的可以看看:
https://github.com/Oldpan/Simple_Ticket_Reservation_System

 

  点赞
本篇文章采用 署名-非商业性使用-禁止演绎 4.0 国际 进行许可
转载请务必注明来源: https://oldpan.me/archives/django-simple_ticket_reservation_system

   关注Oldpan博客微信公众号,你最需要的及时推送给你。


发表评论

邮箱地址不会被公开。 必填项已用*标注

评论审核已启用。您的评论可能需要一段时间后才能被显示。