mrbs

一、mrbs

mrbs:(meeting room booking system)
会议室预订系统

二、效果

三、models

from django.db import models

# Create your models here.

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", on_delete=models.CASCADE)
    room = models.ForeignKey("Room", on_delete=models.CASCADE)
    date = models.DateField()
    time_choice = (
        (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_choice)

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

    def __str__(self):
        return str(self.user)+'预订了'+str(self.room)
models.py

 知识点:

1.AbstractUser 
AUTH_USER_MODEL = "app01.UserInfo"
class UserInfo(AbstractUser):
tel = models.CharField(max_length=32)

2.联合唯一 (time_choice)
time_choice = (
(1,'8:00'),
...
) 存的是key 显示的是value,且只能存key

time_id = models.IntegerField(choices=time_choice)

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

3.makemigrations / migrate

4.admin.py
admin.site.register(UserInfo)
admin.site.register(Book)
admin.site.register(Room)

5.createsuperuser
yuan yuan1234 / alex alex1234

四、login

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>

<form action="" method="post">
    {% csrf_token %}
    用户名:<input type="text" name="user">
    密码: <input type="password" name="pwd">
    <input type="submit">
</form>

</body>
</html>
login.html
from django.contrib import admin
from django.urls import path

from app01 import views

urlpatterns = [
    path('admin/', admin.site.urls),
    path('login/', views.login),
    path('index/', views.index),
    path('book/', views.book),
]
urls.py
from django.shortcuts import render,HttpResponse,redirect
from django.contrib import auth

def login(request):
    if request.method == 'POST':
        user = request.POST.get('user')
        pwd = request.POST.get('pwd')

        user = auth.authenticate(username = user,password = pwd )
        if user:
            auth.login(request,user) # request.user
            return redirect('/index/')

    return render(request,'login.html')
views.py - login

知识点:

1.auth
from django.contrib import auth
user = auth.authenticate(username = user,password = pwd )
if user:
auth.login(request,user) # request.user
return redirect('/index/')

五、index

 知识点:

<table class="table table-bordered table-striped">
<thead>
<tr>
<th>会议室时间</th>
{% for time in time_choice %}
<th>{{ time.1 }}</th>
{% endfor %}
</tr>
</thead>
<tbody>
{{ htmls|safe }}
</tbody>

</table>
1.后台渲染html,不在模板处理数据,因为后台更方便一些
time_choice = Book.time_choice

room_list = Room.objects.all()

# 当天
date = datetime.datetime.now().date() # 年月日 datefield = datetime.datetime()
book_date = request.GET.get('book_date', date)

book_list = Book.objects.filter(date=book_date)

2.htmls

htmls = ""
for room in room_list:
htmls += "<tr><td>" + room.caption + "(" + str(room.num) + ")</td>"
for time in time_choice:
flag = False
for book in book_list:
if book.room.pk == room.pk and book.time_id == time[0]:
# 意味这个单元格已被预定
flag = True
break

if flag:
if request.user.pk == book.user.pk:
htmls += "<td class='active item' room_id=" + str(room.pk) + " time_id=" + str(
time[0]) + ">" + book.user.username + "</td>"
else:
htmls += "<td class='another_active item' room_id=" + str(room.pk) + " time_id=" + str(
time[0]) + ">" + book.user.username + "</td>"
else:
htmls += "<td class='item' room_id=" + str(room.pk) + " time_id=" + str(time[0]) + "></td>"

htmls += '</tr>'

print(htmls)

六、book

前端 组织 数据:

// room_id 为键,time_id 为值  {1:[4,5],2:[4,] }   {3:[9,10]}
var POST_DATA = {
"ADD":{},
"DEL":{}
};

// 为td 绑定 单击事件
function BindTd() {
$('.item').click(function () {

var room_id = $(this).attr('room_id');
var time_id = $(this).attr('time_id');

//取消预订
if($(this).hasClass('active')){
$(this).removeClass('active').empty();
if(POST_DATA.DEL[room_id]){
POST_DATA.DEL[room_id].push(time_id)
}else{
POST_DATA.DEL[room_id] = [time_id]
}

}
//临时取消预订
else if($(this).hasClass('td_active')){
$(this).removeClass('td_active');
{#POST_DATA.ADD[room_id].pop()#} //这个是删除最后一个 在这不对!
// 删除指定的 元素
POST_DATA.ADD[room_id].splice(POST_DATA.ADD[room_id].indexOf(time_id),1)

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

}

})
}

BindTd();

  

//发送 ajax
$('.keep').click(function () {
$.ajax({
url:'/book/',
type:'post',
headers:{"X-CSRFToken":$.cookie('csrftoken')},
data:{
choose_date:CHOOSE_DATE,
post_data:JSON.stringify(POST_DATA)
},
dataType:"json",
success:function (data) {
console.log(data);
if(data.state){
//预订成功
location.href = ''
}else{
alert('预订的房间已经被预订');
location.href=""
}
}

})
});

  日历插件

  。。。

后台 处理 数据:

1. json.loads()

2. 批量插入预订 数据

3. Q查询

4. 删除预订 数据

import json

def book(request):
post_data = json.loads(request.POST.get('post_data'))
# {'ADD': {'1': ['5', '7'], '3': ['4']}, 'DEL': {'2': ['9']}}

choose_date = request.POST.get("choose_date")

res = {"state": True, "msg": None}
try:
# 添加预订
book_list = []
for room_id, time_id_list in post_data["ADD"].items():
for time_id in time_id_list:
book_obj = Book(user=request.user, room_id=room_id, time_id=time_id, date=choose_date)
book_list.append(book_obj)

Book.objects.bulk_create(book_list)

# 删除预订
from django.db.models import Q
# post_data["DEL"]: {"2":["2","3"]}

remove_book = Q()
for room_id, time_id_list in post_data["DEL"].items():
temp = Q()
for time_id in time_id_list:
temp.children.append(("room_id", room_id))
temp.children.append(("time_id", time_id))
temp.children.append(("user_id", request.user.pk))
temp.children.append(("date", choose_date))
remove_book.add(temp, "OR")
if remove_book:
Book.objects.filter(remove_book).delete()

except Exception as e:
res["state"] = False
res["msg"] = str(e)

return HttpResponse(json.dumps(res))

方式1:
q=Q()
q.connection="or"
q.children.append("pk",1)
q.children.append("user_id",1)
q.children.append("room_id",1)

Book.objects.filter(q)


方式2:
Book.objects.filter(Q(pk=1)|Q(user_id=1)|Q(room_id=1))

七、code

from django.shortcuts import render,HttpResponse,redirect
from django.contrib import auth

def login(request):
    if request.method == 'POST':
        user = request.POST.get('user')
        pwd = request.POST.get('pwd')

        user = auth.authenticate(username = user,password = pwd )
        if user:
            auth.login(request,user) # request.user
            return redirect('/index/')

    return render(request,'login.html')


from .models import *
import datetime

def index(request):
    time_choice = Book.time_choice

    room_list = Room.objects.all()

    # 当天
    date = datetime.datetime.now().date()  # 年月日  datefield = datetime.datetime()
    book_date = request.GET.get('book_date', date)
    book_list = Book.objects.filter(date=book_date)

    print('book_list', book_list)
    htmls = ""
    for room in room_list:
        htmls += "<tr><td>" + room.caption + "(" + str(room.num) + ")</td>"
        for time in time_choice:

            flag = False
            for book in book_list:
                if book.room.pk == room.pk and book.time_id == time[0]:
                    # 意味这个单元格已被预定
                    flag = True
                    break

            if flag:
                if request.user.pk == book.user.pk:
                    htmls += "<td class='active item' room_id=" + str(room.pk) + " time_id=" + str(
                        time[0]) + ">" + book.user.username + "</td>"
                else:
                    htmls += "<td class='another_active item' room_id=" + str(room.pk) + " time_id=" + str(
                        time[0]) + ">" + book.user.username + "</td>"
            else:
                htmls += "<td class='item' room_id=" + str(room.pk) + " time_id=" + str(time[0]) + "></td>"

        htmls += '</tr>'

    print(htmls)

    return render(request, 'index.html', locals())

import json

def book(request):
    post_data = json.loads(request.POST.get('post_data'))
    # {'ADD': {'1': ['5', '7'], '3': ['4']}, 'DEL': {'2': ['9']}}

    choose_date = request.POST.get("choose_date")

    res = {"state": True, "msg": None}
    try:
        # 添加预订
        book_list = []
        for room_id, time_id_list in post_data["ADD"].items():
            for time_id in time_id_list:
                book_obj = Book(user=request.user, room_id=room_id, time_id=time_id, date=choose_date)
                book_list.append(book_obj)

        Book.objects.bulk_create(book_list)

        # 删除预订
        from django.db.models import Q
        # post_data["DEL"]: {"2":["2","3"]}

        remove_book = Q()
        for room_id, time_id_list in post_data["DEL"].items():
            temp = Q()
            for time_id in time_id_list:
                temp.children.append(("room_id", room_id))
                temp.children.append(("time_id", time_id))
                temp.children.append(("user_id", request.user.pk))
                temp.children.append(("date", choose_date))
                remove_book.add(temp, "OR")
        if remove_book:
            Book.objects.filter(remove_book).delete()

    except Exception as e:
        res["state"] = False
        res["msg"] = str(e)

    return HttpResponse(json.dumps(res))
views.py

index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>index</title>
    <link rel="stylesheet" href="/static/bootstrap/css/bootstrap.css">
    <script src="/static/js/jquery-1.12.4.min.js"></script>
    <script src="/static/js/jquery.cookie.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: green!important; color: white;}
        .another_active{background-color: #336699;color: white;}
        .td_active{background-color: lightblue;}
    </style>

</head>
<body>

<h3>会议室预订,欢迎:{{ request.user.username }}</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>


<table class="table table-bordered table-striped">
    <thead>
    <tr>
        <th>会议室时间</th>
        {% for time in time_choice %}
            <th>{{ time.1 }}</th>
        {% endfor %}
    </tr>
    </thead>
    <tbody>
    {{ htmls|safe }}

    </tbody>

</table>
<button class="btn btn-success pull-right keep">保存</button>

<script type="text/javascript">

    // 日期格式化方法
    Date.prototype.yuan = function (fmt) { //author: meizz
        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;
    };


    // room_id 为键,time_id 为值  {1:[4,5],2:[4,] }   {3:[9,10]}
    var POST_DATA = {
        "ADD":{},
        "DEL":{}
    };

    // 为td 绑定 单击事件
    function BindTd() {
        $('.item').click(function () {

            var room_id = $(this).attr('room_id');
            var time_id = $(this).attr('time_id');

            //取消预订
            if($(this).hasClass('active')){
                $(this).removeClass('active').empty();
                if(POST_DATA.DEL[room_id]){
                    POST_DATA.DEL[room_id].push(time_id)
                }else{
                    POST_DATA.DEL[room_id] = [time_id]
                }

            }
            //临时取消预订
            else if($(this).hasClass('td_active')){
                $(this).removeClass('td_active');
                {#POST_DATA.ADD[room_id].pop()#}  //这个是删除最后一个 在这不对!
                // 删除指定的 元素
                POST_DATA.ADD[room_id].splice(POST_DATA.ADD[room_id].indexOf(time_id),1)

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

            }

        })
    }
    BindTd();

    // 日期
    if (location.search.slice(11)){
        CHOOSE_DATE = location.search.slice(11)
    }
    else {
        CHOOSE_DATE = new Date().yuan('yyyy-MM-dd');
    }

    //发送 ajax
    $('.keep').click(function () {
        $.ajax({
            url:'/book/',
            type:'post',
            headers:{"X-CSRFToken":$.cookie('csrftoken')},
            data:{
                choose_date:CHOOSE_DATE,
                post_data:JSON.stringify(POST_DATA)
            },
            dataType:"json",
            success:function (data) {
                console.log(data);
                if(data.state){
                    //预订成功
                    location.href = ''
                }else{
                    alert('预订的房间已经被预订');
                    location.href=""
                }
            }

        })
    });

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


    function book_query(e) {
        CHOOSE_DATE=e.date.yuan("yyyy-MM-dd");
        location.href="/index/?book_date="+CHOOSE_DATE;
    }

</script>

</body>
</html>
index.html

https://github.com/alice-bj/mrbs_0

原文地址:https://www.cnblogs.com/alice-bj/p/9190564.html