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 }

 

posted @ 2020-12-19 21:21  ABDM  阅读(132)  评论(0编辑  收藏  举报