会议室预定(可作为插件使用)
Posted ゛竹先森゜
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了会议室预定(可作为插件使用)相关的知识,希望对你有一定的参考价值。
会议室预定(小项目)
该项目仍旧是用Django框架完成的,此项目的重点在于前端页面中有关预定的操作
首先建表,这里用的表较少,一共三张表,表结构如下:
from django.db import models class UserInfo(models.Model): name = models.CharField(verbose_name=\'用户姓名\', max_length=32) password = models.CharField(verbose_name=\'密码\', max_length=32) class MeetingRoom(models.Model): title = models.CharField(verbose_name=\'会议室\', max_length=32) class Booking(models.Model): user = models.ForeignKey(verbose_name=\'用户\', to=\'UserInfo\') room = models.ForeignKey(verbose_name=\'会议室\', to=\'MeetingRoom\') booking_date = models.DateField(verbose_name=\'预定日期\') time_choices = ( (1, \'8:00\'), (2, \'9:00\'), (3, \'10:00\'), (4, \'11:00\'), (5, \'12:00\'), (6, \'13:00\'), (7, \'14:00\'), (8, \'15:00\'), (9, \'16:00\'), (10, \'17:00\'), (11, \'18:00\'), (12, \'19:00\'), (13, \'20:00\'), ) booking_time = models.IntegerField(verbose_name=\'预定时间段\', choices=time_choices) class Meta: unique_together = ( (\'booking_date\', \'booking_time\', \'room\') )
接下来分配路由(项目较为简单,所以并没有写注册的页面,这里是直接将用户数据录入数据库了,若想使项目更完善,可自行添加注册功能。)
from django.conf.urls import url from django.contrib import admin from meet import views urlpatterns = [ url(r\'^admin/\', admin.site.urls), url(r\'^login/$\', views.login), url(r\'^index/$\', views.index), url(r\'^booking/$\', views.booking), url(r\'^log_out/$\', views.log_out), ]
然后是静态文件static的配置
STATIC_URL = \'/static/\' STATICFILES_DIRS=[ os.path.join(BASE_DIR, \'meet\',\'static\'),#别名所指的实际文件夹路径 ]
这里我们用到两个插件,分别是datetimepicker和sweetalert2,前者是在前端页面对Date进行扩展的时间工具,后者是对alert进行美化的一共工具,如不想使用后者,直接用alert即可。
从网上下载两个插件,放入static下。
登录、注销功能
url(r\'^login/$\', views.login), url(r\'^log_out/$\', views.log_out),
#注销功能 def log_out(request): del request.session[\'user_info\'] return redirect(\'/index/\') def login(request): """ 用户登录 """ if request.method == "GET": form = LoginForm() return render(request, \'login.html\', {\'form\': form}) else: form = LoginForm(request.POST) if form.is_valid(): rmb = form.cleaned_data.pop(\'rmb\')#一周免登陆选项 user = models.UserInfo.objects.filter(**form.cleaned_data).first() if user: request.session[\'user_info\'] = {\'id\': user.id, \'name\': user.name} if rmb:#若勾选了一周免登陆选项 request.session.set_expiry(60 * 60 * 24 * 30) return redirect(\'/index/\') else: form.add_error(\'password\', \'密码错误\') return render(request, \'login.html\', {\'form\': form}) else: return render(request, \'login.html\', {\'form\': form})
上面用到了form组件如下:
from django.forms import Form from django.forms import fields from django.forms import widgets class LoginForm(Form): name = fields.CharField( required=True, error_messages={\'required\': \'用户名不能为空\'}, widget=widgets.TextInput(attrs={\'class\': \'form-control\', \'placeholder\': \'用户名\', \'id\': \'name\'}) ) password = fields.CharField( required=True, error_messages={\'required\': \'密码不能为空\'}, widget=widgets.PasswordInput(attrs={\'class\': \'form-control\', \'placeholder\': \'密码\', \'id\': \'password\'}) ) #一周免登陆选项 rmb = fields.BooleanField(required=False, widget=widgets.CheckboxInput(attrs={\'value\': 1}))
{% load staticfiles %} <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <link rel="stylesheet" href="{% static \'bootstrap-3.3.7-dist/css/bootstrap.min.css\' %}"> <style> </style> </head> <body> <div style="width: 500px;margin: 50px auto;padding-top: 180px;"> <form class="form-horizontal" method="post" novalidate> {% csrf_token %} <div class="form-group"> <label for="name" class="col-sm-2 control-label">用户名:</label> <div class="col-sm-10"> {{ form.name }} {{ form.errors.name.0 }} </div> </div> <div class="form-group"> <label for="password" class="col-sm-2 control-label">密码:</label> <div class="col-sm-10"> {{ form.password }} {{ form.errors.password.0 }} </div> </div> <div class="form-group"> <div class="col-sm-offset-2 col-sm-10"> <div class="checkbox"> <label> {{ form.rmb }} 一周内免登录 </label> </div> </div> </div> <div class="form-group"> <div class="col-sm-offset-2 col-sm-10"> <button type="submit" class="btn btn-primary">登录</button> </div> </div> </form> </div> </body> </html>
之后用于验证登陆与否的装饰器:
#验证登陆与否的装饰器 def auth(func): def inner(request, *args, **kwargs): user_info = request.session.get(\'user_info\') if not user_info: return redirect(\'/login/\') return func(request, *args, **kwargs) return inner
登录功能较为简单,不做详述,接下来我们做首页
我们的预定功能就在首页中,所以首页是重中之重。
难点:index.html中的js:tbody的生成、datetimepicker插件的使用、前后端发送的时间格式的转换、后端录入数据库的操作
url(r\'^index/$\', views.index), url(r\'^booking/$\', views.booking),
#views.py中:
import json
import datetime
from django.shortcuts import render, HttpResponse, redirect
from django.http import JsonResponse
from meet import models
from meet.form import *
from django.db.models import Q
from django.db.utils import IntegrityError
@auth def index(request): """ 会议室预定首页 :param request: :return: """ #拿到所有的时间段 time_choices = models.Booking.time_choices user_info = request.session.get(\'user_info\') name=user_info[\'name\'] return render(request, \'index.html\', {\'time_choices\': time_choices,\'name\':name})
{% load staticfiles %} <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <link rel="stylesheet" href="{% static \'bootstrap-3.3.7-dist/css/bootstrap.min.css\' %}"> <link rel="stylesheet" href="{% static \'datetimepicker/bootstrap-datetimepicker.min.css\' %}"> <link rel="stylesheet" href="{% static \'sweetalert2/sweetalert2.css\' %}"> {# <link rel="stylesheet" href="{% static \'mycss/index.css\' %}">#} <style> body { font-size: 14px; } .shade { position: fixed; z-index: 1040; top: 0; left: 0; right: 0; bottom: 0; background-color: #999; filter: alpha(opacity=50); -moz-opacity: 0.5; opacity: 0.5; } .loading { position: fixed; z-index: 1050; top: 40%; left: 50%; height: 32px; width: 32px; margin: 0 0 0 -16px; background: url(/static/img/loading.gif); } .clearfix{ padding: 10px 0; } .input-group{ width: 230px; float:left; } .save-btn{ padding: 0 5px;float: left } table > tbody td { height: 80px; width: 80px; text-align: center; vertical-align: middle; } table > tbody td.chosen { background-color: #ebccd1; } table > tbody td.selected { background-color:#d58512 ; } .mycolor{ background-color: #EEE685; } .unable{ color: #002a80; opacity: 0.5; } </style> </head> <body> <div class="container"> <div class="panel panel-primary"> <div class="panel-heading"> <h1 class="text-center">会议室预定</h1> </div> <div class="panel-body"> <div class="clearfix"> <div style="float: left;color: red" id="errors"></div> <div class=\'input-group\'> {# 时间插件#} <input type=\'text\' class="form-control" id=\'datetimepicker11\' placeholder="请选择日期"/> <span class="input-group-addon"> <span class="glyphicon glyphicon-calendar"> </span> </span> </div> <div class="save-btn"> <a id="save" class="btn btn-primary">保存</a> </div> <div class="pull-right"> <b>hello {{ name }} </b> <a href="/log_out/">注销</a> </div> </div> <table class="table table-bordered table-striped" style="border:1px solid red"> <thead> <tr> <th>会议室</th> {# 拿到从后端发过来的所有时间段#} {% for choice in time_choices %} <th>{{ choice.1 }}</th> {% endfor %} </tr> </thead> <tbody id="tBody"> {# tbody中的内容包含未预定信息和预定信息,且需要实时更新以上是关于会议室预定(可作为插件使用)的主要内容,如果未能解决你的问题,请参考以下文章