• 会议室预定设计


    一、目标

      - 会议室预定

    二、业务流程

      - 用户登录

      - 预定会议室

      - 退订会议室

      - 选择日期;今日以及以后日期

    三、表结构设计

       - 用户表

      - 会议室表

      - 记录表

        用户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;
                 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提交

  • 相关阅读:
    OSU!

    旅行
    序列
    致摸鱼两千年后的你
    生成函数
    小x游世界树

    画画
    OSU!
  • 原文地址:https://www.cnblogs.com/morgana/p/8496479.html
Copyright © 2020-2023  润新知