会议室预定系统

1、models.py

 1 from django.db import models
 2 
 3 # Create your models here.
 4 class MeetingRoom(models.Model):
 5     '''会议室'''
 6     name = models.CharField(max_length=32,verbose_name="会议室名称")
 7     class Meta:
 8         verbose_name_plural = "会议室"
 9 
10     def __str__(self):
11         return self.name
12 
13 class ReserveRecord(models.Model):
14     '''预定记录表'''
15     data = models.DateField(verbose_name="预定日期")
16     user = models.ForeignKey(to="UserInfo",verbose_name="预订人")
17     room = models.ForeignKey(to="MeetingRoom",verbose_name="预定房间")
18     time1 = (
19         (1,"8.00"),
20         (2,"9.00"),
21         (3,"10.00"),
22         (4,"11.00"),
23         (5,"12.00"),
24         (6,"13.00"),
25         (7,"14.00"),
26         (8,"15.00"),
27         (9,"16.00"),
28         (10,"17.00"),
29         (11,"18.00"),
30         (12,"19.00"),
31         (13,"20.00"),
32     )
33     timeline = models.IntegerField(choices=time1,verbose_name="预定时间")
34     class Meta:
35         verbose_name_plural = "预订记录表"
36         unique_together = (
37             ('data', 'timeline', 'room')
38         )
39     def __str__(self):
40         return self.user.username
41 
42 class UserInfo(models.Model):
43     '''用户信息'''
44     username = models.CharField(max_length=32,verbose_name="用户名",unique=True)
45     password = models.CharField(max_length=64,verbose_name="密码")
46     class Meta:
47         verbose_name_plural = "用户信息"
48 
49     def __str__(self):
50         return self.username
View Code

2、urls.py

 1 """会议室预定 URL Configuration
 2 
 3 The `urlpatterns` list routes URLs to views. For more information please see:
 4     https://docs.djangoproject.com/en/1.11/topics/http/urls/
 5 Examples:
 6 Function views
 7     1. Add an import:  from my_app import views
 8     2. Add a URL to urlpatterns:  url(r'^$', views.home, name='home')
 9 Class-based views
10     1. Add an import:  from other_app.views import Home
11     2. Add a URL to urlpatterns:  url(r'^$', Home.as_view(), name='home')
12 Including another URLconf
13     1. Import the include() function: from django.conf.urls import url, include
14     2. Add a URL to urlpatterns:  url(r'^blog/', include('blog.urls'))
15 """
16 from django.conf.urls import url
17 from django.contrib import admin
18 from app01 import views
19 urlpatterns = [
20     url(r'^admin/', admin.site.urls),
21     url(r'^index/$', views.index),
22     url(r'^recording/$', views.recording),
23     url(r'^login/$', views.login),
24 ]
View Code

3、views.py

  1 from django.forms import Form
  2 from django.forms import fields
  3 from django.forms import widgets
  4 from django.http.response import JsonResponse
  5 from django.shortcuts import render,redirect
  6 from app01 import models
  7 # Create your views here.
  8 import datetime
  9 import json
 10 # def index(request):
 11 #     #查看所有会议室的名称
 12 #     metting_list = models.ReserveRecord.time1
 13 #     print("4444444",metting_list)
 14 #     room_obj = models.MeetingRoom.objects.all()
 15 #
 16 #     return render(request,"index.html",{"metting_list":metting_list,"room_obj":room_obj})
 17 
 18 class LoginForm(Form):
 19     username = fields.CharField(
 20         max_length=8,
 21         required=True,
 22         error_messages={
 23             "max_length":"用户名长度不能大于8位",
 24             "required":"用户名不能为空",
 25         },
 26         # label="用户名",
 27         # label_suffix=":",
 28         widget=widgets.TextInput(attrs={"class":"form-control","placeholder":"username","id":"username"})
 29     )
 30     password = fields.CharField(
 31         max_length=8,
 32         min_length=3,
 33         required=True,
 34         error_messages={
 35             "max_length":"密码长度不能大于8位",
 36             "min_length":"密码长度不能小于3位",
 37             "required":"密码不能为空",
 38         },
 39         # label="密码",
 40         # label_suffix=":",
 41         widget=widgets.PasswordInput(attrs={"class":"form-control","placeholder":"password","id":"password"}))
 42 def login(request):
 43     if request.method =="GET":
 44         form = LoginForm()
 45         return render(request,"login.html",{"form":form})
 46     else:
 47         form = LoginForm(data=request.POST)
 48         if form.is_valid():
 49             user = models.UserInfo.objects.filter(**form.cleaned_data).first()
 50             if user:
 51                 request.session["userinfo"]={"id":user.id,"name":user.username}
 52                 return redirect("/index/")
 53                 # cookie的方式设置
 54                 # obj.set_cookie("name","zzz")
 55                 # obj.set_signed_cookie("id",user.id,salt="aaaa")
 56                 # obj.set_signed_cookie("id1",user.id)
 57                 # return obj
 58         else:
 59             form.add_error('password','密码错误')
 60             return render(request,"login.html",{"form":form})
 61     return render(request, "login.html", {"form": form})
 62 
 63 
 64 def index(request):
 65     metting_list = models.ReserveRecord.time1
 66     return render(request,"index.html",{"metting_list":metting_list})
 67 
 68 def recording(request):
 69     response = {"status": True, "msg": None, "data": None}
 70     if request.method == "GET":
 71         current_data = datetime.datetime.now().date()  #日期类型
 72         #=======================获取指定日期所有的预定信息=========================
 73         try:
 74             ajax_date= request.GET.get("date")  #字符串类型
 75             # print(ajax_date,"============")
 76             ajax_date = datetime.datetime.strptime(ajax_date, '%Y-%m-%d').date()
 77             # print("date....",ajax_date)
 78             if ajax_date < current_data:
 79                 raise Exception("查询时间不能是以前的时间")
 80             recording_list = models.ReserveRecord.objects.filter(data=ajax_date)  #查询的这一天的所有的记录
 81             # print(recording_list,"recording_list")  # [OBJ(1,room_id,user_id.time_id.data),OBJ(2,room_id,user_id.time_id.data)]
 82             # 吧这样的数据处理成字典的形式,提升查询速度
 83             # {
 84             #     1:{   #room_id
 85             #         2:{"username":2,"user_id":3}  #2表示time_id
 86             #     }
 87             # }
 88             recrding_dict = {}
 89             for i in recording_list:
 90                if i.room_id not in recrding_dict:
 91                     recrding_dict[i.room_id]={i.timeline:{"username":i.user.username,"user_id":i.user_id}}
 92                else:
 93                    # recrding_dict[i.room_id][i.timeline] = {i.timeline:{"username":i.user.username,"user_id":i.user_id}}
 94                    recrding_dict[i.room_id][i.timeline] = {"username":i.user.username,"user_id":i.user_id}
 95             print('--------',recrding_dict)
 96             #获取所有的会议室信息
 97             room_list = models.MeetingRoom.objects.all()
 98             #===========================生成会议室信息========================
 99             data = []
100             for room in room_list:
101                 print(room)
102                 tr = []
103                 tr.append({"text": room.name, "attrs": {}})
104                 for tm in models.ReserveRecord.time1:
105                     td = {"text": "", "attrs": {"room_id": room.id, "time_id": tm[0]}}
106                     if room.id in recrding_dict and tm[0] in recrding_dict[room.id]:
107                         #已预订,不确定是谁预定的,还得判断一下
108                         td['attrs']['class'] = "chosen"
109                         if recrding_dict[room.id][tm[0]]['user_id'] == request.session["userinfo"]["id"]:
110                             #如果是自己预定
111                             td['text'] = ''
112                         else:
113                             #如果是别人预定,加一个disabled属性不可编辑,只有自己的能编辑
114                             td['text'] = recrding_dict[room.id][tm[0]]['username']
115                             td['attrs']['disable'] = True
116                     tr.append(td)
117                 data.append(tr)
118             print('-==========',data)
119             response["data"] = data
120         except Exception as e:
121             response["status"] = True
122             response["msg"] = str(e)
123     else:
124         try:
125             current_date = datetime.datetime.now().date()
126             ajax_date = request.POST.get("date")
127             ajax_date = datetime.datetime.strptime(ajax_date, '%Y-%m-%d').date()
128             if ajax_date < current_date:
129                  raise Exception("查询时间不是当前的时间")
130             post_data = json.loads(request.POST.get("data"))  #由于发过来的数据是字符串,所以要转一下才能是字典
131             print(post_data)  #{'ADD': {'1': ['5', '4'], '2': ['4', '7']}, 'DEL': {'2': ['4']}}}
132             date = request.POST.get("date")   #获取日期
133             # print(date)  #2017-12-12
134             # 拿到数据以后
135             # 如果time_id在ADD里面有,在Del里面也有值,就删除了,因为数据库里面已经有值了。就直接把add里的和del里的删除就行了
136             for room_id ,time_list in post_data["DEL"].items():
137                 if room_id  not in post_data["ADD"]:
138                     continue
139                 else:
140                     for time_id in list(time_list):
141                         if time_id in post_data["ADD"][room_id]:
142                             post_data["ADD"][room_id].remove(time_id)
143                             post_data["DEL"][room_id].remove(time_id)
144                 # print(post_data)
145             #新增数据
146             reserverecord_obj_list = []
147             for room_id ,time_list in post_data["ADD"].items():
148                 for time_id in time_list:
149                     # models.ReserveRecord.objects.create(room_id=room_id,time_id=time_id,date=date,user=request.session["userinfo"]["id"])
150                     obj = models.ReserveRecord(room_id=room_id,timeline=time_id,data=date,user_id=request.session["userinfo"]["id"])
151                     reserverecord_obj_list.append(obj)
152             models.ReserveRecord.objects.bulk_create(reserverecord_obj_list)
153 
154             #删除会议室预定信息
155             from django.db.models import Q
156             remove_reserverecord = Q()
157             for room_id,time_list in post_data["DEL"].items():
158                 for time_id in time_list:
159                     temp = Q()
160                     temp.connector = "AND"
161                     temp.children.append(("user_id",request.session["userinfo"]["id"]))
162                     temp.children.append(("data",date))
163                     temp.children.append(("room_id",room_id))
164                     temp.children.append(("timeline",time_id))
165 
166                     remove_reserverecord.add(temp,"OR")
167             if remove_reserverecord:
168                 print(models.ReserveRecord.objects.filter(remove_reserverecord))
169                 models.ReserveRecord.objects.filter(remove_reserverecord).delete()
170             # print(remove_reserverecord,"remove_reserverecord")
171         except Exception as e:
172             response["status"] = False
173             response["msg"] = str(e)
174     return JsonResponse(response)
View Code

4、templates

 1 <!DOCTYPE html>
 2 <html lang="en">
 3 <head>
 4     <meta charset="UTF-8">
 5     <meta http-equiv="X-UA-Compatible" content="IE=edge">
 6     <meta name="viewport" content="width=device-width">
 7     <link rel="stylesheet" href="/static/bootstrap-3.3.7-dist/css/bootstrap.min.css">
 8     <script src="/static/jquery-3.2.1.min.js"></script>
 9     <script src="/static/bootstrap-3.3.7-dist/js/bootstrap.min.js"></script>
10     <title>Title</title>
11     <style>
12         .container {
13             margin-top: 100px;
14         }
15     </style>
16 </head>
17 <body>
18 <form action="/login/" method="post" novalidate>
19     {% csrf_token %}
20     <div class="container">
21         <h3 style="text-align: center">请先登录</h3>
22         <div class="row">
23             <div class="col-md-4 col-md-offset-4">
24                 <div class="form-group">
25                     <label for="username">用户名</label>
26                     {{ form.username }}
27                     <p style="color: red">{{ form.errors.username.0 }}</p>
28                 </div>
29                 <div class="form-group">
30                     <label for="password">密码</label>
31                     {{ form.password }}
32                     <p style="color: red">{{ form.errors.password.0 }}</p>
33                 </div>
34                 <input type="submit" value="登录" class="btn btn-success col-sm-7 col-md-offset-2">
35             </div>
36         </div>
37 
38     </div>
39 
40 </form>
41 </body>
42 </html>
login.html
  1 <!DOCTYPE html>
  2 <html lang="en">
  3 <head>
  4     <meta charset="UTF-8">
  5     <meta http-equiv="X-UA-Compatible" content="IE=edge">
  6     <meta name="viewport" content="width=device-width">
  7     <title>Title</title>
  8     <link rel="stylesheet" href="/static/bootstrap-3.3.7-dist/css/bootstrap.min.css">
  9     <link rel="stylesheet" href="/static/css/index.css">
 10     <link rel="stylesheet" href="/static/bootstrap-datetimepicker-master/css/bootstrap-datetimepicker.css">
 11     <script src="/static/jquery-3.2.1.min.js"></script>
 12     <script src="/static/bootstrap-datetimepicker-master/js/bootstrap-datetimepicker.js"></script>
 13     <script src="/static/bootstrap-datetimepicker-master/js/locales/bootstrap-datetimepicker.fr.js"></script>
 14     <script src="/static/bootstrap-datetimepicker-master/js/locales/bootstrap-datetimepicker.zh-CN.js"></script>
 15 </head>
 16 <body>
 17 <div class="container">
 18     <div class="row">
 19         <div class="col-md-11">
 20             <h1>会议室预定</h1>
 21             <div class="data pull-right">
 22                 <button class="btn btn-primary" id="save">保存</button>
 23             </div>
 24             {#            日期#}
 25             <div class='col-sm-4 pull-right'>
 26                 <div class="form-group">
 27                     <div class='input-group date' id='datetimepicker2'  placeholder="请选择日期">
 28                         <input type='text' class="form-control"/>
 29                         <span class="input-group-addon">
 30                     <span class="glyphicon glyphicon-calendar"></span>
 31                 </span>
 32                     </div>
 33                 </div>
 34             </div>
 35 {#            表格#}
 36             <div>
 37                 <table class="table table-bordered">
 38                     <thead>
 39                     <th>会议室</th>
 40                       {% for metting in metting_list %}
 41                       <th>{{ metting.1 }}</th>
 42                       {% endfor %}
 43                     </thead>
 44                     <tbody id = "tBody">
 45 {#                        方式一:也可以这样渲染#}
 46 {#                        {% for room in room_obj %}#}
 47 {#                        <tr>#}
 48 {#                            <td>{{ room.name }}</td>#}
 49 {#                            {% for metting in metting_list %}#}
 50 {#                            <td></td>#}
 51 {#                            {% endfor %}#}
 52 {#                        </tr>#}
 53 {#                        {% endfor %}#}
 54 {#                            方式二#}
 55 {#                        发送ajax请求渲染#}
 56                     
 57                     </tbody>
 58                 </table>
 59             </div>
 60 {#            加载框#}
 61             <div class="shade hide"></div>
 62             <div class="loading hide"></div>
 63         </div>
 64     </div>
 65 </div>
 66 <script>
 67     //对Date的扩展
 68     // 对Date的扩展,将 Date 转化为指定格式的String
 69     // 月(M)、日(d)、小时(h)、分(m)、秒(s)、季度(q) 可以用 1-2 个占位符,
 70     // 年(y)可以用 1-4 个占位符,毫秒(S)只能用 1 个占位符(是 1-3 位的数字)
 71     // 例子:
 72     // (new Date()).Format("yyyy-MM-dd hh:mm:ss.S") ==> 2006-07-02 08:09:04.423
 73     // (new Date()).Format("yyyy-M-d h:m:s.S")      ==> 2006-7-2 8:9:4.18
 74     Date.prototype.Format = function (fmt) { //author: meizz
 75         var o = {
 76             "M+": this.getMonth() + 1, //月份
 77             "d+": this.getDate(), // 78             "h+": this.getHours(), //小时
 79             "m+": this.getMinutes(), // 80             "s+": this.getSeconds(), // 81             "q+": Math.floor((this.getMonth() + 3) / 3), //季度
 82             "S": this.getMilliseconds() //毫秒
 83         };
 84         if (/(y+)/.test(fmt)) fmt = fmt.replace(RegExp.$1, (this.getFullYear() + "").substr(4 - RegExp.$1.length));
 85         for (var k in o)
 86             if (new RegExp("(" + k + ")").test(fmt)) fmt = fmt.replace(RegExp.$1, (RegExp.$1.length == 1) ? (o[k]) : (("00" + o[k]).substr(("" + o[k]).length)));
 87         return fmt;
 88     };
 89 
 90     $(function(){    //一开始加载的时候执行这个函数
 91         initDatepickle();
 92         initRecoringInfo(new Date().Format("yyyy-MM-dd"));
 93         initTdEvent();
 94         initSaveEvent();
 95     });
 96 
 97     POST_DATA = {
 98         "ADD":{},
 99         "DEL":{}
100     };
101     //时间控件初始化
102     function initDatepickle() {
103        $('#datetimepicker2').datetimepicker({
104         minView: "month",//设置只显示到月份
105         format: 'yyyy-mm-dd',//显示格式
106 {#        autoclose: true,//选完自动关闭#}
107         todayBtn: true,
108         language:"zh-CN",
109          startDate: new Date(),  //以前的日期不能点
110         bootcssVer:3  //小箭头
111         }).on('changeDate', changeDate);
112     }
113     //点击日期插件的时候改变的函数
114     function changeDate(ev) {
115 {#        console.log(ev.date);  //Wed Dec 13 2017 20:43:08 GMT+0800 (中国标准时间)#}
116         CHOISE_DATE = ev.date.Format("yyyy-MM-dd");  //拿到的是插件的日期
117         initRecoringInfo(CHOISE_DATE);
118 
119     }
120 
121     CHOISE_DATE = new Date().Format("yyyy-MM-dd");  //当change的时候会修改日期,它拿到的是当前的日期
122    //获取预定记录发送ajax请求
123     function initRecoringInfo(date) {   //这里穿进来的date就是上面转换成字符串的时间
124 {#        刚开始发送ajax的时候加载#}
125         $(".shade,.loading").removeClass("hide");
126         $(function () {
127             $.ajax({
128                 url: "/recording/",
129                 type: "get",
130                 data: {"date": date},
131                 success: function (data) {
132                     $(".shade,.loading").addClass("hide");
133                     if (data.status) {
134                         $("#tBody").empty();
135                         $.each(data.data, function (i, item) {
136 {#                                                console.log(i,item);#}
137                             var $tr = $("<tr>");
138                             $.each(item, function (j, k) {
139                                 {#                        console.log(j,k);#}
140                                 var $td = $("<td>");
141                                 $td.text(k.text);
142                                 $.each(k.attrs, function (m, n) {
143                                     console.log(m, n);
144                                     $td.attr(m, n)
145                                 });
146                                 $tr.append($td);
147                                 {#                        if (k.chosen){#}
148                                 {#                            $("class").addClass("chosen")#}
149                                 {#                        }#}
150                             });
151                             $("#tBody").append($tr);
152                         });
153 
154                         //吧del,add里面有的内容清空
155                         CHOSEN_DATE = new Date().Format('yyyy-MM-dd');
156                         POST_DATA = {
157                             DEL:{},
158                             ADD:{}
159                         };
160                     }
161                     else {
162                         alert(data.msg)
163                     }
164                 },
165                 error:function () {
166                      $(".shade,.loading").removeClass("hide");
167                      alert("异常错误")
168                 }
169             })
170         })
171     }
172 
173     //给td绑定事件,处理数据
174     function initTdEvent(){
175         //事件委派
176         $("tBody").on("click","td[time_id][disable!='true']",function () {
177             //添加一个样式
178             var room_id = $(this).attr("room_id");
179             var time_id = $(this).attr("time_id");
180             if ($(this).hasClass("chosen")){
181                 $(this).removeClass("chosen");
182                 $(this).text("");
183                 //退订room_id = 1 ,time_id = 5的
184                 if (POST_DATA.DEL[room_id]) {
185                     //如果有room_id,就添加一个time_id
186                     POST_DATA.DEL[room_id].push(time_id)
187                 }else {
188                     POST_DATA.DEL[room_id] = [time_id]
189                 }
190             }
191             else if ($(this).hasClass("temp")){
192                 //取消预定
193                 $(this).removeClass("temp");
194                 //从add中吧数据删除(先找到索引,然后如果存在就删除)
195                 var index = POST_DATA.ADD[room_id].indexOf(time_id);
196                 if (index!==-1) {
197                     POST_DATA.ADD[room_id].splice(index,1)  //索引为n的删除一个
198                 }
199             }else {
200                 //要预定,吧预定的结果添加进去
201                 $(this).addClass("temp");
202                  if (POST_DATA.ADD[room_id]) {
203                     //如果有room_id,就添加一个time_id
204                     POST_DATA.ADD[room_id].push(time_id)
205                 }else {
206                     POST_DATA.ADD[room_id] = [time_id]
207                 }
208             }
209         })
210     }
211 
212     //通过ajax想后台发数据
213     function initSaveEvent() {
214         $("#save").click(function () {
215             $.ajax({
216                 url:"/recording/",
217                 type:"post",
218                 data:{
219                        data:JSON.stringify(POST_DATA),  //要发送的用户传过来的时间
220                        date:CHOISE_DATE,  //发送的日期时间
221                        csrfmiddlewaretoken:'{{ csrf_token }}'
222                     },
223 
224                 success:function (data) {
225                     console.log(data);
226                     if (data.status){
227                         initRecoringInfo(CHOISE_DATE)
228                     }
229                     else {
230                         alert(data.msg)
231                     }
232                 }
233             })
234         })
235     }
236 </script>
237 </body>
238 </html>
index.html
 1 table{
 2     margin-top: 80px;
 3 }
 4 td{
 5     height: 80px;
 6 }
 7 .chosen{
 8     background-color: gold;
 9 }
10 .shade {
11             position: fixed;
12             z-index: 1040;
13             top: 0;
14             left: 0;
15             right: 0;
16             bottom: 0;
17             background-color: #999;
18             filter: alpha(opacity=50);
19             -moz-opacity: 0.5;
20             opacity: 0.5;
21         }
22 
23 .loading {
24             position: fixed;
25             z-index: 1050;
26             top: 40%;
27             left: 50%;
28             height: 32px;
29             width: 32px;
30             margin: 0 0 0 -16px;
31             background: url(/static/img/loading.gif);
32 }
33 .temp{
34     background-color: salmon;
35 }
index.css

 

posted on 2017-12-13 15:12  海燕。  阅读(2780)  评论(3编辑  收藏  举报