會議室預定設計


一、目標

  - 會議室預定

二、業務流程

  - 用戶登錄

  - 預定會議室

  - 退訂會議室

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

三、表結構設計

   - 用戶表

  - 會議室表

  - 記錄表

    用戶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提交

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM