4.1 会议室预定系统 (补充版)

0. 目的效果

1. 创建Django项目

2. 数据库表

2.1 models.py

from django.db import models

# Create your models here.

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

# 继承django自带的user表,自定义User model
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):
    """
    会议室预定信息
    who在 when预定了 which room?
    """
    user = models.ForeignKey("UserInfo",on_delete=models.CASCADE)  # on_delete=models.CASCADE 级联删除
    room = models.ForeignKey("Room",on_delete=models.CASCADE)
    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)

2.2 settings.AUTH_USER_MODEL

自定义User model

settings.py

# 用户可以自定义User model了, 如果需要外键使用user model
AUTH_USER_MODEL = "app01.UserInfo"

2.3 数据库生成与迁移

python manage.py makemigrations
python manage.py migrate

 

2.4 添加2个superuser

python manage.py createsuperuser

2.5 settings设置日志:ORM执行SQL

LOGGING = {
    'version': 1,
    'disable_existing_loggers': False,
    'handlers': {
        'console':{
            'level':'DEBUG',
            'class':'logging.StreamHandler',
        },
    },
    'loggers': {
        'django.db.backends': {
            'handlers': ['console'],
            'propagate': True,
            'level':'DEBUG',
        },
    }
}

2.6 知识点

(1)显示名称

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

(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)使用settings.AUTH_USER_MODEL

参考博客:如何正确使用 Django的User Model

 

3. 登录页面

 3.1 urls

from django.contrib import admin
from django.urls import path

from app01 import views  # impor app01下的view 对应到 url

urlpatterns = [
    path('admin/', admin.site.urls),
    path('login/', views.login),
    path('index/', views.index),
]

 3.2 views

from django.shortcuts import render
from django.shortcuts import redirect # 重定向,跳转

# Create your views here.
from django.contrib import auth  # django自带的用户认证

def login(request):
    # 登录验证
    if request.method == "POST":
        user=request.POST.get("user")
        pwd=request.POST.get("pwd")

        # django用户认证判定
        user=auth.authenticate(username=user,password=pwd)
        if user:
            auth.login(request,user)  # request.user  # 注册下
            return redirect("/index/")
    return render(request,"login.html")

def index(request):

    return render(request,"index.html")

3.3 login.html

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

<form action="" method="post">
    {% csrf_token %}  
    username:<input type="text" name="user">
    password:<input type="password" name="pwd">
    <input type="submit">
</form>

</body>
</html>

3.4 index.html

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

3.5 项目启动,登录验证

3.6 知识点

auth认证

from django.contrib import auth  # django自带的用户认证

# django用户认证判定
user=auth.authenticate(username=user,password=pwd)
if user:
    auth.login(request,user)  # request.user  # 注册下
    return redirect("/index/")

 4.admin操作

4.1 SQLite配置

 

 4.2 添加2条数据

 

4.3 admin.py中注册模型表

admin.py

from django.contrib import admin

# Register your models here.
# 注册模型表,显示在admin页面中
from .models import UserInfo,Room,Book

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

 在admin主页中可以显示表

 4.4 admin添加data

5.index页面

5.1 导入bootstrap,jquery,datetimepicker

5.2 版本1:前台渲染

 

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    {# 导入bootstrap和jquery #}
    <link rel="stylesheet" href="/static/bootstrap/css/bootstrap.css">
    <script src="/static/js/jquery-1.12.4.min.js"></script>
    {# 导入datetimepicker #}
    <script src="/static/datetimepicker/bootstrap-datetimepicker.min.js"></script>
    <script src="/static/datetimepicker//bootstrap-datetimepicker.zh-CN.js"></script>
</head>
<body>

<h3>会议室预定</h3>

<table class="table table-bordered table-striped">
    <thead>
        <tr>
            <th>会议室/时间</th>
            {# 循环会议室时间 #}
                {# <th>8:00</th> #}
                {# <th>9:00</th> #}
                {# <th>10:00</th> #}
            {% for time_choice in time_choices %}
                <th>{{ time_choice.1 }}</th>
            {% endfor %}
        </tr>
    </thead>

    <tbody>
        {% for room in room_list %}
            <tr>
                <td>{{ room.caption }}</td>

                {% for time_choice in time_choices %}
                    <td></td>
                {% endfor %}

            </tr>
        {% endfor %}
    </tbody>

</table>
</body>
</html>

5.3 版本2:后端渲染

(1)为什么要在后端渲染

后台渲染html,不在模板处理数据,因为后台更方便一些

(2)如何后端渲染??

(3)进化版本

5.4 预定信息显示,不同登录人显示不同

(1)如何匹配?

 (2)如何取出来

 

(3)登录人不同显示不同color

 

5.5 代码:版本2

 (1)效果图

  

 (2)view.py

from django.shortcuts import render
from django.shortcuts import redirect # 重定向,跳转

# Create your views here.
from django.contrib import auth  # django自带的用户认证

def login(request):
    # 登录验证
    if request.method == "POST":
        user=request.POST.get("user")
        pwd=request.POST.get("pwd")

        # django用户认证判定
        user=auth.authenticate(username=user,password=pwd)
        if user:
            auth.login(request,user)  # request.user  # 注册下
            return redirect("/index/")
    return render(request,"login.html")

import datetime
from .models import Book,Room
def index(request):
    time_choices = Book.time_choices
    room_list = Room.objects.all()

    # 预定msg
    date=datetime.datetime.now().date()  # 当前日期
    book_date=request.GET.get("book_date",date)   #预定日期
    book_list=Book.objects.filter(date=book_date)  # 过滤出表中预定的msg

    # LowB版本
    htmls_lowb = """
            <tr>
                <td>401(12)</td>
                <td class="active_other item" room_id="1" time_id="13"></td>
                <td class="active_other item" room_id="2" time_id="13"></td>
                <td class="active_other item" room_id="3" time_id="13"></td>
                <td class="active_other item" room_id="4" time_id="13"></td>
                <td class="active_other item" room_id="5" time_id="13"></td>
                <td class="active_other item" room_id="6" time_id="13"></td>
                <td class="active_other item" room_id="7" time_id="13"></td>
                <td class="active_other item" room_id="7" time_id="13"></td>
                <td class="active_other item" room_id="7" time_id="13"></td>
                <td class="active_other item" room_id="7" time_id="13"></td>
                <td class="active_other item" room_id="7" time_id="13"></td>
                <td class="active_other item" room_id="7" time_id="13"></td>
                <td class="active_other item" room_id="7" time_id="13"></td>
            </tr>
            """

    # Nb版本
    htmls = ""
    for room in room_list:
        htmls += "<tr><td>{}({})</td>".format(room.caption,room.num)

        for time_choice in time_choices:
            book = None
            flag = False  # 是否已经被预定
            for book in book_list:
                if book.room.pk==room.pk and book.time_id==time_choice[0]:
                # 意味着这个单元格已经预定
                    flag=True
                    break

            if flag: # 被预定

                if request.user.pk == book.user.pk:
                    # 登录人不同显示颜色不同
                    htmls += "<td class='active' room_id='{}' time_id='{}'>{}</td>".format(room.pk,time_choice[0],book.user.username)
                else:
                    htmls += "<td class='another_active' room_id='{}' time_id='{}'>{}</td>".format(room.pk,time_choice[0],book.user.username)

            else:  # 没被预定
                htmls += "<td room_id='{}' time_id='{}'></td>".format(room.pk, time_choice[0])
        htmls += "</tr>"

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

(3)index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    {# 导入bootstrap和jquery #}
    <link rel="stylesheet" href="/static/bootstrap/css/bootstrap.css">
    <script src="/static/js/jquery-1.12.4.min.js"></script>
    {# 导入datetimepicker #}
    <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: blue;
            color: white;
        }
    </style>
</head>
<body>

<h3>会议室预定</h3>

<table class="table table-bordered table-striped">
    <thead>
        <tr>
            <th>会议室/时间</th>
            {# 循环会议室时间 #}
                {# <th>8:00</th> #}
                {# <th>9:00</th> #}
                {# <th>10:00</th> #}
            {% for time_choice in time_choices %}
                <th>{{ time_choice.1 }}</th>
            {% endfor %}
        </tr>
    </thead>

    <tbody>
    {# 后端渲染 #}
        {{ htmls|safe }}
    </tbody>

</table>
</body>
</html>

6. Book预定

 6.1 为td绑定单击事件

 6.2 构建提交data

(1)js中要掌握的

// js 字符串 数组 obejct{}  的常用方法

(2)增加预定

(3)取消预订

   

 (3)临时取消预订

 

 6.3提交按钮

(1)日历插件

日历插件

 (2)url

 (3)view视图

  后台 处理 数据:

    1. json.loads()

    2. 批量插入预订 数据

    3. Q查询

    4. 删除预订 数据

import json
from django.db.models import Q
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)

        # 删除预订
        # 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")
                temp=Q()   # 同一room的不同时间预定的不能删除,要temp重新置到0

        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))

(4)前端模板

 (5)click的ajax请求

    //保存按钮,发送ajax
    $('.keep').click(function () {

        //alert(111111)

        $.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('该Room已经被预定了');
                    location.href='';
                }
            }
    })

    });

6.4 知识点 Q查询

方式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))


7.Code

7.1 url.py

"""MBRS URL Configuration

The `urlpatterns` list routes URLs to views. For more information please see:
    https://docs.djangoproject.com/en/2.2/topics/http/urls/
Examples:
Function views
    1. Add an import:  from my_app import views
    2. Add a URL to urlpatterns:  path('', views.home, name='home')
Class-based views
    1. Add an import:  from other_app.views import Home
    2. Add a URL to urlpatterns:  path('', Home.as_view(), name='home')
Including another URLconf
    1. Import the include() function: from django.urls import include, path
    2. Add a URL to urlpatterns:  path('blog/', include('blog.urls'))
"""
from django.contrib import admin
from django.urls import path

from app01 import views  # impor app01下的view 对应到 url

urlpatterns = [
    path('admin/', admin.site.urls),
    path('login/', views.login),
    path('index/', views.index),
    path('book/', views.book),
]
View Code

7.2 settings.py 

"""
Django settings for MBRS project.

Generated by 'django-admin startproject' using Django 2.2.1.

For more information on this file, see
https://docs.djangoproject.com/en/2.2/topics/settings/

For the full list of settings and their values, see
https://docs.djangoproject.com/en/2.2/ref/settings/
"""

import os

# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))


# Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/2.2/howto/deployment/checklist/

# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = 't)e_9hf^ov2p-h65p3)at&di&qp7l(94fn@###zn891uass2gx'

# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True

ALLOWED_HOSTS = []


# Application definition

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'app01.apps.App01Config',
]

MIDDLEWARE = [
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
]

ROOT_URLCONF = 'MBRS.urls'

TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [os.path.join(BASE_DIR, 'templates')]
        ,
        'APP_DIRS': True,
        'OPTIONS': {
            'context_processors': [
                'django.template.context_processors.debug',
                'django.template.context_processors.request',
                'django.contrib.auth.context_processors.auth',
                'django.contrib.messages.context_processors.messages',
            ],
        },
    },
]

WSGI_APPLICATION = 'MBRS.wsgi.application'


# Database
# https://docs.djangoproject.com/en/2.2/ref/settings/#databases

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
    }
}


# Password validation
# https://docs.djangoproject.com/en/2.2/ref/settings/#auth-password-validators

AUTH_PASSWORD_VALIDATORS = [
    {
        'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
    },
    {
        'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
    },
    {
        'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
    },
    {
        'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
    },
]


# Internationalization
# https://docs.djangoproject.com/en/2.2/topics/i18n/

LANGUAGE_CODE = 'en-us'

TIME_ZONE = 'UTC'

USE_I18N = True

USE_L10N = True

USE_TZ = True


# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/2.2/howto/static-files/

STATIC_URL = '/static/'


# 用户可以自定义User model了, 如果需要外键使用user model
AUTH_USER_MODEL = "app01.UserInfo"


LOGGING = {
    'version': 1,
    'disable_existing_loggers': False,
    'handlers': {
        'console':{
            'level':'DEBUG',
            'class':'logging.StreamHandler',
        },
    },
    'loggers': {
        'django.db.backends': {
            'handlers': ['console'],
            'propagate': True,
            'level':'DEBUG',
        },
    }
}
View Code

7.3 views.py

from django.shortcuts import HttpResponse
from django.shortcuts import render
from django.shortcuts import redirect # 重定向,跳转

# Create your views here.
from django.contrib import auth  # django自带的用户认证


def login(request):
    # 登录验证
    if request.method == "POST":
        user=request.POST.get("user")
        pwd=request.POST.get("pwd")

        # django用户认证判定
        user=auth.authenticate(username=user,password=pwd)
        if user:
            auth.login(request,user)  # request.user  # 注册下
            return redirect("/index/")
    return render(request,"login.html")


import datetime
from .models import Book,Room
def index(request):
    time_choices = Book.time_choices
    room_list = Room.objects.all()

    # 预定msg
    date=datetime.datetime.now().date()  # 当前日期
    book_date=request.GET.get("book_date",date)   #预定日期
    book_list=Book.objects.filter(date=book_date)  # 过滤出表中预定的msg

    # LowB版本
    htmls_lowb = """
            <tr>
                <td>401(12)</td>
                <td class="active_other item" room_id="1" time_id="13"></td>
                <td class="active_other item" room_id="2" time_id="13"></td>
                <td class="active_other item" room_id="3" time_id="13"></td>
                <td class="active_other item" room_id="4" time_id="13"></td>
                <td class="active_other item" room_id="5" time_id="13"></td>
                <td class="active_other item" room_id="6" time_id="13"></td>
                <td class="active_other item" room_id="7" time_id="13"></td>
                <td class="active_other item" room_id="7" time_id="13"></td>
                <td class="active_other item" room_id="7" time_id="13"></td>
                <td class="active_other item" room_id="7" time_id="13"></td>
                <td class="active_other item" room_id="7" time_id="13"></td>
                <td class="active_other item" room_id="7" time_id="13"></td>
                <td class="active_other item" room_id="7" time_id="13"></td>
            </tr>
            """

    # Nb版本
    htmls = ""
    for room in room_list:
        htmls += "<tr><td>{}({})</td>".format(room.caption,room.num)

        for time_choice in time_choices:
            book = None
            flag = False  # 是否已经被预定
            for book in book_list:
                if book.room.pk==room.pk and book.time_id==time_choice[0]:
                # 意味着这个单元格已经预定
                    flag=True
                    break

            if flag: # 被预定

                if request.user.pk == book.user.pk:
                    # 登录人不同显示颜色不同
                    htmls += "<td class='active item' room_id='{}' time_id='{}'>{}</td>".format(room.pk,time_choice[0],book.user.username)
                else:
                    htmls += "<td class='another_active item' room_id='{}' time_id='{}'>{}</td>".format(room.pk,time_choice[0],book.user.username)

            else:  # 没被预定
                htmls += "<td class='item' room_id='{}' time_id='{}'></td>".format(room.pk, time_choice[0])
        htmls += "</tr>"


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


import json
from django.db.models import Q
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)

        # 删除预订
        # 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")
                temp=Q()   # 同一room的不同时间预定的不能删除,要temp重新置到0

        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))

# 链接: https://pan.baidu.com/s/1nzY8khXOrlvtFX2367E2sg 密码: qu3a
View Code

7.4 login.html

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

<form action="" method="post">
    {% csrf_token %}
    username:<input type="text" name="user">
    password:<input type="password" name="pwd">
    <input type="submit">
</form>

</body>
</html>
View Code

7.5 index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    {# 导入bootstrap和jquery #}
    <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>
    {# 导入datetimepicker #}
    <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: blue;
            color: white;
        }

        .td_active{
            background-color: #2aabd2;
            color: white;
        }
    </style>
</head>
<body>

<h2>Hi {{ request.user.username }}</h2>
<h3>会议室预定</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>
            {# 循环会议室时间 #}
                {# <th>8:00</th> #}
                {# <th>9:00</th> #}
                {# <th>10:00</th> #}
            {% for time_choice in time_choices %}
                <th>{{ time_choice.1 }}</th>
            {% endfor %}
        </tr>
    </thead>

    <tbody>
    {# 后端渲染 #}
        {{ htmls|safe }}
    </tbody>

</table>


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

<script>

     // 日期格式化方法
    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;
    };


    //构建提交数据
    var POST_DATA={
        //"ADD":{1:[4,5],2:[4]},   // 键 room_id 1
        //"DEL":{3:[9,10]},       // 值 time_id [4,5]
        "ADD":{},
        "DEL":{},
    };

    //为td绑定单击事件
    function BindTd() {
        $(".item").click(function () {
            //alert(123);
            //alert($(this).attr("room_id"));

            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]    //第一次del中添加data
                }

            }

            // 临时取消预订
            else if($(this).hasClass("td_active")){
                $(this).removeClass("td_active");

                //按照指定元素删除???
                // POST_DATA.ADD[room_id].remove(time_id) // remove无定义
                // 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 () {

        //alert(111111)

        $.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('该Room已经被预定了');
                    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>
View Code

 7.6 github

https://github.com/venicid/MBRS

原文地址:https://www.cnblogs.com/venicid/p/11212538.html