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

简介: 简易车票预订系统简单的车票预订系统,采用django2.0搭建。实现的功能:预订功能:该系统使用户能够预订两天之内(今明两天)的车票,23点之后(不包含)不能预订当天的车票;信息反馈:用户输入车票日期,若...

简易车票预订系统

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

实现的功能:

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

界面展示

这里写图片描述

简单的购票界面,使用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>

相关操作截图

这里写图片描述

购票预订成功

这里写图片描述

购票信息查询

这里写图片描述

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

这里写图片描述

此刻再进行查询查询不到

这里写图片描述

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

这里写图片描述

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

后记

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

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

目录
相关文章
|
3天前
|
Python
Django 框架的路由系统
Django 框架的路由系统
18 6
|
1月前
|
机器学习/深度学习 数据处理 数据库
基于Django的深度学习视频分类Web系统
基于Django的深度学习视频分类Web系统
53 4
基于Django的深度学习视频分类Web系统
|
1月前
|
数据库 数据库管理 Python
#736421#基于django的个人博客系统
#736421#基于django的个人博客系统
37 4
#736421#基于django的个人博客系统
|
1月前
|
机器学习/深度学习 监控 数据挖掘
基于Django和百度飞桨模型的情感识别Web系统
基于Django和百度飞桨模型的情感识别Web系统
37 5
|
1月前
|
数据库 数据库管理 Python
#73623#基于django的园区对比系统
#73623#基于django的园区对比系统
37 4
|
1月前
|
数据库 数据安全/隐私保护 数据库管理
#099473#基于django的毕业生信息管理招聘系统
#099473#基于django的毕业生信息管理招聘系统
38 4
|
1月前
|
监控 应用服务中间件 网络安全
#637481#基于django和neo4j的日志分析系统
#637481#基于django和neo4j的日志分析系统
33 4
|
1月前
|
数据库 数据安全/隐私保护 数据库管理
#765372#基于django和neo4j的通用数据展示系统
#765372#基于django和neo4j的通用数据展示系统
22 1
|
2月前
|
机器学习/深度学习 人工智能 算法
【新闻文本分类识别系统】Python+卷积神经网络算法+人工智能+深度学习+计算机毕设项目+Django网页界面平台
文本分类识别系统。本系统使用Python作为主要开发语言,首先收集了10种中文文本数据集("体育类", "财经类", "房产类", "家居类", "教育类", "科技类", "时尚类", "时政类", "游戏类", "娱乐类"),然后基于TensorFlow搭建CNN卷积神经网络算法模型。通过对数据集进行多轮迭代训练,最后得到一个识别精度较高的模型,并保存为本地的h5格式。然后使用Django开发Web网页端操作界面,实现用户上传一段文本识别其所属的类别。
90 1
【新闻文本分类识别系统】Python+卷积神经网络算法+人工智能+深度学习+计算机毕设项目+Django网页界面平台
|
2月前
|
Linux Python
解决django项目报错很离谱的报错之RuntimeError: populate() isn't reentrant
解决django项目报错很离谱的报错之RuntimeError: populate() isn't reentrant