Project://Meeting_Room

models

from django.db import models
from django.contrib.auth.models import AbstractUser

class UserInfo(AbstractUser):
    tel=models.CharField(max_length=32)

class Room(models.Model):
    """
    会议室表
    """
    caption = models.CharField(max_length=32)
    num = models.IntegerField()


    def __str__(self):
        return self.caption


class Book(models.Model):
    """
    会议室预定信息
    """
    user = models.ForeignKey('UserInfo')
    room = models.ForeignKey('Room')
    date = models.DateField()
    time_choices = (
        (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'),
    )
    time_id = models.IntegerField(choices=time_choices)

    class Meta:
        unique_together = (
            ('room','date','time_id'),
        )


    def __str__(self):
        return str(self.user)+"预定了"+str(self.room)

views

from django.shortcuts import render, redirect, HttpResponse
from .models import *
from django.http import JsonResponse
from django.contrib import auth
import datetime,json


def index(request):
    current_date = datetime.datetime.now().date()  # 取到当前时间
    book_date = request.GET.get("book_date", current_date.strftime("%Y-%m-%d"))  # 取到预定时间

    book_date = datetime.datetime.strptime(book_date, "%Y-%m-%d")  # 格式化时间
    time_choices = Book.time_choices  # 取到model里定义的时间

    room_list = Room.objects.all()  # 取到所有房间
    book_list = Book.objects.filter(date=book_date)  # 筛选当前时间的所有预定信息

    html = ""

    for room in room_list:  # 取到每一个的房间信息
        s = '<tr><td>{0}({1})</td>'.format(room.caption, room.num)
        for item in time_choices:  # 取到每一个可以预定的时间段
            flag = False
            for book in book_list:  # 取到每一个预定信息book
                if book.room.caption == room.caption and book.time_id == item[0]:  # 如果每一个预定信息的房间名称和时间段匹配成功
                    flag = True
                    break
            if flag:  # 如果预定信息存在
                if request.user.pk != book.user.pk:  # 如果当前登录用户不是预定用户
                    s += '<td class="active_other item" room_id="{0}" time_id="{1}">{2}</td>'.format(room.pk, item[0],
                                                                                                     book.user.username)
                else:  # 如果当前登录用户就是预定用户
                    s += '<td class="active item" room_id="{0}" time_id="{1}">{2}</td>'.format(room.pk, item[0],
                                                                                               book.user.username)
            else:  # 如果当前房间当前时段没人预定,显示空白
                s += '<td class="item" room_id="{0}" time_id="{1}"></td>'.format(room.pk, item[0])

        s += "</tr>"
        html += s  # 拼出tr单元格
    return render(request, 'index.html', locals())


def book(request):
    print(request.POST)
    response = {'status': True, 'msg': None, 'data': None}
    try:
        choice_date = request.POST.get('date')  # 取出从前端get的数据
        choice_date = datetime.datetime.strptime(choice_date, '%Y-%m-%d').date()  # 转换日期成指定格式

        post_data = json.loads(request.POST.get('data'))  # 取出ajax传来的数据,并反序列化

        # 优化 既在添加字典又在取消字典中 == 不添加 也不取消
        for room_id, time_list in post_data['DEL'].items():  # 循环字典中每一个删除信息
            if room_id not in post_data['ADD']:                     # 如果循环到的删除房间 没在 添加房间的字典中
                continue                                             # 结束当前循环进入下一个循环
            for time_id in list(time_list):                  # 循环删除字典中每个房间的时间段
                if time_id in post_data['ADD'][room_id]:    # 如果这个时间段在当前循环房间  添加预订 的字典中
                    post_data['ADD'][room_id].remove(time_id)           # 从添加预订的字典中移除 这个时间段
                    post_data['DEL'][room_id].remove(time_id)           # 从取消预订的字典中移除 这个时间段

        # 增加预定
        book_obj_list = []
        for room_id, time_list in post_data['ADD'].items():
            for time_id in time_list:
                obj = Book(room_id=room_id, time_id=time_id, user_id=request.user.pk, date=choice_date)
                book_obj_list.append(obj)  # 添加到预订房间的 列表中
        Book.objects.bulk_create(book_obj_list)  # 批量创建到数据库

        # 删除会议室预定信息
        print(post_data['DEL'])
        from django.db.models import Q
        remove_booking = Q()
        for room_id, time_id_list in post_data['DEL'].items():
            for time_id in time_id_list:
                temp = Q()
                temp.connector = 'AND'
                temp.children.append(('user_id', request.user.pk,))
                temp.children.append(('date', choice_date))
                temp.children.append(('room_id', room_id,))
                temp.children.append(('time_id', time_id,))

                remove_booking.add(temp, 'OR')
        if remove_booking:
            Book.objects.filter(remove_booking).delete()

    except Exception as e:
        response['status'] = False
        response['msg'] = str(e)

    return JsonResponse(response)


def login(request):
    if request.method == "POST":
        user = request.POST.get("user")
        pwd = request.POST.get("pwd")
        user = auth.authenticate(username=user, password=pwd)  # 用auth 模块对当前登录用户进行验证
        if user:
            auth.login(request, user)
            return redirect("/index/")

    return render(request, "login.html")

index

<!DOCTYPE html>
<html>
<head>


    <link rel="stylesheet" href="/static/bootstrap/css/bootstrap.css">
    <script src="/static/js/jquery-1.12.4.min.js"></script>

    <script src="/static/datetimepicker/bootstrap-datetimepicker.min.js"></script>
    <script src="/static/datetimepicker//bootstrap-datetimepicker.zh-CN.js"></script>

    <style type="text/css">

        .active {
            background-color: #ffc322 !important;
            color: black;
            text-align: center;
            font-size: 16px;
        }

        .td_active {
            background-color: greenyellow !important;
        }

        .active_other {
            background-color: rebeccapurple;
            color: white;
            text-align: center;
            font-size: 16px;
        }


    </style>
</head>
<body>
<h3>会议室预订,{{ request.user }}</h3>

<div class="calender pull-right">
    <div class='input-group' style=" 230px;">
        <input type='text' class="form-control" id='datetimepicker11' placeholder="请选择日期"/>
        <span class="input-group-addon">
                <span class="glyphicon glyphicon-calendar">
                </span>
            </span>

    </div>
</div>
{% csrf_token %}
<table class="table table-bordered table-striped">
    <thead>
    <tr>
        <th>会议室/时间</th>
        {% for item in time_choices %}
            <th>{{ item.1 }}</th>
        {% endfor %}
    </tr>
    </thead>

    <tbody>
    {{ html|safe }}
    </tbody>
</table>
<button class="keep btn btn-primary pull-right" style="margin-right: 100px">保存</button>

<script>
    // 给JS字符串Date添加自定义方法Format
    Date.prototype.Format = function (fmt) {
        var o = {
            "M+": this.getMonth() + 1, //月份
            "d+": this.getDate(), //日
            "h+": this.getHours(), //小时
            "m+": this.getMinutes(), //分
            "s+": this.getSeconds(), //秒
            "q+": Math.floor((this.getMonth() + 3) / 3), //季度
            "S": this.getMilliseconds() //毫秒
        };
        if (/(y+)/.test(fmt)) fmt = fmt.replace(RegExp.$1, (this.getFullYear() + "").substr(4 - RegExp.$1.length));
        for (var k in o)
            if (new RegExp("(" + k + ")").test(fmt)) fmt = fmt.replace(RegExp.$1, (RegExp.$1.length == 1) ? (o[k]) : (("00" + o[k]).substr(("" + o[k]).length)));
        return fmt;
    };

    // 给日历插件绑定事件
    $(function () {
        $('#datetimepicker11').datetimepicker({
            minView: "month",
            language: "zh-CN",
            sideBySide: true,
            format: 'yyyy-mm-dd',
            startDate: new Date(),
            bootcssVer: 3,
            autoclose: true,
        }).on('changeDate', book_query);
        bindTd();
    });

    // 切片取会议室预定的时间
    if (location.search.slice(11)) {
        CHOSEN_DATE = location.search.slice(11)     // 如果url中有时间,就有时间
    }
    else {
        CHOSEN_DATE = new Date().Format('yyyy-MM-dd');      // 如果url中没有时间,取当前时间
    }


    function book_query(ev) {
        CHOSEN_DATE = ev.date.Format('yyyy-MM-dd');
        location.href = "/index/?book_date=" + CHOSEN_DATE
    }

    // 定义两个发送给后端的字典
    var POST_DATA = {
        DEL: {},
        ADD: {},

    };

    // 定义绑定td函数
    function bindTd() {
        $(".item").click(function () {
            if ("{{ request.user.username }}") {
                var room_id = $(this).attr('room_id');
                var time_id = $(this).attr('time_id');

                if ($(this).hasClass("active")) {    // 如果当前点击的单元格有active属性
                    $(this).removeClass('active').empty();
                    // 退订 roo_id=4   time_id=5
                    // 退订 roo_id=4   time_id=6
                    if (POST_DATA.DEL[room_id]) {
                        POST_DATA.DEL[room_id].push(time_id);
                    } else {
                        POST_DATA.DEL[room_id] = [time_id];
                    }
                }
                else {
                    $(this).addClass('td_active');
                    if (POST_DATA.ADD[room_id]) {
                        POST_DATA.ADD[room_id].push(time_id);
                    } else {
                        POST_DATA.ADD[room_id] = [time_id];
                    }
                }

            }
            else {
                location.href = "/login/"
            }
        })
    }

    // 保存按钮功能
    $(".keep").click(function () {

        console.log(POST_DATA);
        $("td.td_activ").each(function () {

        });
        // 用ajax把数据发送给后端
        $.ajax({
            url: "/book/",
            type: "POST",
            data: {data: JSON.stringify(POST_DATA), date: CHOSEN_DATE, csrfmiddlewaretoken: '{{ csrf_token }}'},
            success: function (data) {
                if (data.status) {
                    location.href = ""
                }
                else {
                    alert("不能选择其他人已预订的房间");
                    location.href = ""
                }
            }
        })
    })
</script>
</body>
</html>
原文地址:https://www.cnblogs.com/iyouyue/p/8671132.html