1. 程式人生 > 實用技巧 >028 會議室預定設計與會議室預定程式碼

028 會議室預定設計與會議室預定程式碼

會議室預定設計

一、目標

  - 會議室預定

二、業務流程

  - 使用者登入

  - 預定會議室

  - 退訂會議室

  - 選擇日期;今日以及以後日期

三、表結構設計

   - 使用者表

  - 會議室表

  - 記錄表

    使用者ID   會議室ID    時間   時間段

    user_id   room_id   data   timeline

      1     1      2017-12-11  1

from django.db import models

# Create your models here.
class MeetingRoom(models.Model):
    
'''會議室''' name = models.CharField(max_length=32,verbose_name="會議室名稱") class Meta: verbose_name_plural = "會議室" def __str__(self): return self.name class ReserveRecord(models.Model): '''預定記錄表''' data = models.DateField(verbose_name="預定日期") user = models.ForeignKey(to="
UserInfo",verbose_name="預訂人") room = models.ForeignKey(to="MeetingRoom",verbose_name="預定房間") time1 = ( (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"), ) timeline = models.IntegerField(choices=time1,verbose_name="預定時間") class Meta: verbose_name_plural = "預訂記錄表" unique_together = ( ('data', 'timeline', 'room') ) def __str__(self): return self.user.username class UserInfo(models.Model): '''使用者資訊''' username = models.CharField(max_length=32,verbose_name="使用者名稱",unique=True) password = models.CharField(max_length=64,verbose_name="密碼") class Meta: verbose_name_plural = "使用者資訊" def __str__(self): return self.username

四、操作細節以及設計的知識點

=========================後端頁面=================
我們可以用ajax的方式,傳送請求。後端返回資料,直接在頁面中渲染。
如何生成這樣的資料
data = [
[{"text":"天上人間","attrs":{}},{"text":"海燕","attrs":{"room_id":1,"time_id":1,"class":"chosen"}},{"text":"","attrs":{"room_id":1,"time_id":1}},{"text":"","attrs":{"room_id":1,"time_id":1}},{"text":"","attrs":{"room_id":1,"time_id":1}}],
[{"text":"夏威夷","attrs":{}},{"text":"","attrs":{"room_id":2,"time_id":2}},{"text":"Frank","attrs":{"room_id":1,"time_id":1,"class":"chosen"}}],
[{"text":"馬爾地夫","attrs":{}},{"text":"","attrs":{"room_id":3,"time_id":3}},{"text":"","attrs":{"room_id":1,"time_id":1}}],
]

有可能有人已經預定了,當沒有chosen的時候就沒有預定.
預定資訊都放在預定表裡了
所以我們得去預定表裡面取一些資料


那麼怎麼獲取預定資訊呢?獲取指定日期所有的預定資訊(也就是這一天的所有預定資訊)
具體操作:
在資料庫裡面新增預定資訊
到底查那天的是不確定的,應該是使用者給發過來的,所以發ajax的時候得發過來一個日期
data:{choice_data:"2017-5-5"}
在views中,獲取日期,但是這個日期是有限制的,必須是大於等於當前的日期,如果是前幾天的就不能在選,都已經過去了,
當前日期等於....data型別
獲取的日期等於...str型別。所以要轉一下。

獲取到的是一個queryset集合[
OBJ(1,room_id,user_id.time_id.data)
OBJ(1,room_id,user_id.time_id.data)
OBJ(1,room_id,user_id.time_id.data)
]
檢測會議室在該時間段是否已預定
在上面這個資料存在則表示已經預定,不存在沒預定
方式一:
利用兩層迴圈來做,但是迴圈的效率不怎麼高,所以也可以用結構化資料的方式

for bk in recording_list:
        if room.id==bk.room.id and bk.timeline==tm[0]:
            td={"text":bk.user.username,"attrs":{"room_id":room.id,"time_id":tm[0],"class":"chosen"}}                    # 如果沒有預定就不加
    tr.append(td)

下面是具體操作

 1 def recording(request):
 2     response = {"status":True,"msg":None,"data":None}
 3     #檢視指定日期所有的預定資訊
 4     ajax_date= request.GET.get("date")  #字串型別
 5     current_data = datetime.datetime.now().date()  #日期型別
 6     ajax_date = datetime.datetime.strptime(ajax_date, '%Y-%m-%d').date()
 7     try:
 8         if ajax_date < current_data:
 9             raise Exception("查詢時間不能是以前的時間")
10         recording_list = models.ReserveRecord.objects.filter(data=ajax_date)
11         print(recording_list,"recording_list")
12         room_list = models.MeetingRoom.objects.all()
13         data = []
14         for room in room_list:
15             tr = []
16             tr.append({"text":room.name,"attrs":{}})
17             for tm in models.ReserveRecord.time1:
18                 # print(tm[1])
19                 td={"text":"","attrs":{"room_id":room.id,"time_id":tm[0]}}
20                 #判斷該房間在該時間段被預定了沒有
21                 # 如果預定了就加上{"class":"chosen"}
22                 for bk in recording_list:
23                     if room.id==bk.room.id and bk.timeline==tm[0]:
24                         td={"text":bk.user.username,"attrs":{"room_id":room.id,"time_id":tm[0],"class":"chosen"}}                    # 如果沒有預定就不加
25                 tr.append(td)
26             data.append(tr)
27 
28             # data = [
29             #     [{"text":"天上人間","attrs":{}},{"text":"海燕","attrs":{"room_id":1,"time_id":1,"class":"chosen"}},{"text":"","attrs":{"room_id":1,"time_id":1}},{"text":"","attrs":{"room_id":1,"time_id":1}},{"text":"","attrs":{"room_id":1,"time_id":1}}],
30             #     [{"text":"夏威夷","attrs":{}},{"text":"","attrs":{"room_id":2,"time_id":2}},{"text":"Frank","attrs":{"room_id":1,"time_id":1,"class":"chosen"}}],
31             #     [{"text":"馬爾地夫","attrs":{}},{"text":"","attrs":{"room_id":3,"time_id":3}},{"text":"","attrs":{"room_id":1,"time_id":1}}],
32             # ]
33             response["data"] = data
34     except Exception as e:
35         response["status"] = True
36         response["msg"] = str(e)
37 
38     return JsonResponse(response)
View Code

吧[
OBJ(1,room_id,user_id.time_id.data)
OBJ(1,room_id,user_id.time_id.data)
OBJ(1,room_id,user_id.time_id.data)
]變成一個字典
查詢中字典的查詢速度是最快的
{
  2: {
    9: {'username': 'egon', 'user_id': 1}
  }
}
1表示room_id,5表示time_id

ecrding_dict = {}
for i in recording_list:
    if i.room_id not in recrding_dict:
        recrding_dict[i.room_id]={i.timeline:{"username":i.user.username,"user_id":i.user_id}}
    else:
        recrding_dict[i.room_id][i.timeline] = {i.timeline:{"username":i.user.username,"user_id":i.user_id}}
print(recrding_dict)

然後看一下它的room_id和time_id在不在字典裡面。如果在裡面已經被預定了,否則沒有被預定
具體實現

def recording(request):
    response = {"status":True,"msg":None,"data":None}
    current_data = datetime.datetime.now().date()  #日期型別
    #檢視指定日期所有的預定資訊
    try:
        ajax_date= request.GET.get("date")  #字串型別
        ajax_date = datetime.datetime.strptime(ajax_date, '%Y-%m-%d').date()
        if ajax_date < current_data:
            raise Exception("查詢時間不能是以前的時間")
        recording_list = models.ReserveRecord.objects.filter(data=ajax_date)  #查詢的這一天的所有的記錄
        print(recording_list,"recording_list")  # [OBJ(1,room_id,user_id.time_id.data),OBJ(2,room_id,user_id.time_id.data)]
       
        recrding_dict = {}
        for i in recording_list:
           if i.room_id not in recrding_dict:
                recrding_dict[i.room_id]={i.timeline:{"username":i.user.username,"user_id":i.user_id}}
           else:
               recrding_dict[i.room_id][i.timeline] = {i.timeline:{"username":i.user.username,"user_id":i.user_id}}
        print(recrding_dict)

        room_list = models.MeetingRoom.objects.all()
        data = []
        for room in room_list:
            tr = []
            tr.append({"text":room.name,"attrs":{}})
            for tm in models.ReserveRecord.time1:
                # print(tm[1])
                # 方式二
                # 判斷該房間在該時間段被預定了沒有, 如果預定了就加上{"class":"chosen"}
                if room.id in recrding_dict and tm[0] in recrding_dict[room.id]:
                    td={"text":recrding_dict[room.id][tm[0]]["username"],"attrs":{"room_id":room.id,"time_id":tm[0],"class":"chosen"}}
                else:
                    td = {"text": "", "attrs": {"room_id": room.id, "time_id": tm[0]}}
                tr.append(td)
            data.append(tr)

     
            response["data"] = data
    except Exception as e:
        response["status"] = True
        response["msg"] = str(e)

    return JsonResponse(response)

前端頁面

======================前端頁面=====================
今天日期怎麼獲取、:
d = new Date()   #當天日期
d.getFullYeat()  #年
d.getMonth()   #月
d.getDate()    #日
=========給字串擴充套件的一個uuuu方法============
String.prototype.uuuu = function(){
    return "zzzz"
}
=========給日期物件擴充套件的一個Format方法============
d = new Date()
Date.prototype.Format = function(){
    ..
}



===============載入框=================
和模態框一樣,也有兩層(遮罩層,載入層)
.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);
        }

那麼什麼時候讓他顯示呢?
預設是隱藏的
當剛開始發ajax的時候載入,獲取成功之後就讓隱藏了
出錯之後也給讓載入



解決forbidden
 function csrfSafeMethod(method) {
        // these HTTP methods do not require CSRF protection
        return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method));
    }
    $.ajaxSetup({
        beforeSend: function (xhr, settings) {
            if (!csrfSafeMethod(settings.type) && !this.crossDomain) {
                xhr.setRequestHeader("X-CSRFToken", $.cookie('csrftoken'));
            }
        }
    });

圖片解析

待續具體操作、、、、、、、、、、

繫結完以後預定或者退訂
  1、預定的時候加個樣式,當點完以後取消預定給移除了
  2、如果是本來就有的,先把有的背景去掉,而且文字清空
  3、點選儲存吧選中的以及取消過的都發到後臺,
    我要預定那些,我要取消那些。要把這些資料傳送過去
    我們通過樣式發過去有點麻煩,我們可以通過一個全域性變數發過去
    POST——DATA = {
      "ADD":{},
      "DEL":{}
    }
    假如:
    POST——DATA = {
    "ADD":{
      room_id time_id
        4: [4,5]
      },
    "DEL":{}
    }
    現在來生成這樣的結構,如果4存在。
    js中的{}物件如果key存在,就有值,如果不存在返回undified


  4、當一開始預定了,然後又不預定給刪除了,這時的資料沒有在資料庫中,從add中吧資料刪除

  5、js中的刪除指定的值, v= [1,2,3,4]
              v.indexOf(3) #找到就找到,找不到就等於-1
              當找到的時候用v.splice(index,1) #刪除索引位置的一個

  6、增加的id有他,刪除的id也有他,先刪除還是先增加?
      POST——DATA = {
        "ADD":{
          1:[5,6]
          2:[5,6,7]
        },
        "DEL":{
          1:[6,7]
          }
        }
    先刪除後新增,因為這是還沒有資料庫呢。原來資料庫就已經有有值了,先從add,和del中刪除了,資料庫就不用再添加了。
    完了批量新增其他的值

  7、給儲存按鈕繫結事件
    吧使用者預定記錄的資料傳送到後臺
    傳送ajax請求

    function initSaveEvent() {
        $("#save").click(function () {
            $.ajax({
                url:"/recording/",
                type:"post",
                data:{
                       data:JSON.stringify(POST_DATA),  //要傳送的使用者傳過來的時間
                       date:CHOISE_DATE,  //傳送的日期時間
                       csrfmiddlewaretoken:'{{ csrf_token }}'
                    },

                success:function (data) {
                    console.log(data);
                    if (data.status){
                        initRecoringInfo(CHOISE_DATE)
                    }
                    else {
                        alert(data.msg)
                    }
                }
            })
        })
    }

  使用者選擇的日期date,怎麼拿呢?在來一個全域性變數
  預設是CHOISE_DATE = new Date().Format("yyyy-MM-dd")
  change 的時候會修改
    function change(){
        CHOISE_DATE = new Date().Format("yyyy-MM-dd")
        initserverecoing(CHOISE_DATE)
    }

    8、csrf驗證的三種方式:
      1、帶著資料發過去
      2、從cookie中拿到,帶著請求頭髮給後臺
      3、在發資料的時候{{ csrf_token }} #不推薦

詳見部落格:http://www.cnblogs.com/haiyan123/p/7837439.html
========================資料傳送到後臺以後======================
發過來的日期和當前的日期還是進行一個比較,
然後在後端處理資料,,該儲存的儲存,該刪除的刪除(刪除的時候用Q查詢,外面是或關係,裡面是or關係)
然後資料如果成功之後,再去傳送ajax請求,呼叫函式

三、涉及到的相關知識點:

1、使用者登入

    使用者登入成功之後吧使用者id和使用者名稱設定在session或者cookie中

    注意:設定cookie的時候要設定成簽名的cookie,也就是加密的cookie

obj = redirect("/index/")
   obj.set_cookie("id",user.id)  #明文的cookie
   obj.set_signed_cookie("id",user.id,salt="aaaa") #密文的cookie return obj

2、一週沒免登入:也就是設定cookie和session的過期時間(預設是兩週)

主動設定超時時間:request.session.set_expiry(60 * 60 * 24 * 30)

3、判斷使用者是否已經登入,有兩種方式:

  方式一:裝飾器(就有幾個函式的時候用裝飾器)

  方式二:中介軟體(大型專案的時候用中介軟體)

4、寫功能的時候獲取並顯示資料

   - 要麼在用模板渲染

   - 要麼返回頁面,ajax獲取資料

5、前端傳送資料

  - Form表單提交

  - Ajax提交

會議室預定系統程式碼

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

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 ]

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>
  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>
 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 }