########################################
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
###############################################
表结构分析 1,会议室表,会议室的名称 2,会议室的预定表,预定的会议室,谁预定的,预定的时间,
###############################################
"""会议室预定 URL Configuration The `urlpatterns` list routes URLs to views. For more information please see: https://docs.djangoproject.com/en/1.11/topics/http/urls/ Examples: Function views 1. Add an import: from my_app import views 2. Add a URL to urlpatterns: url(r'^$', views.home, name='home') Class-based views 1. Add an import: from other_app.views import Home 2. Add a URL to urlpatterns: url(r'^$', Home.as_view(), name='home') Including another URLconf 1. Import the include() function: from django.conf.urls import url, include 2. Add a URL to urlpatterns: url(r'^blog/', include('blog.urls')) """ from django.conf.urls import url from django.contrib import admin from app01 import views urlpatterns = [ url(r'^admin/', admin.site.urls), url(r'^index/$', views.index), url(r'^recording/$', views.recording), url(r'^login/$', views.login), ]
###############################################
from django.forms import Form from django.forms import fields from django.forms import widgets from django.http.response import JsonResponse from django.shortcuts import render,redirect from app01 import models # Create your views here. import datetime import json # def index(request): # #查看所有会议室的名称 # metting_list = models.ReserveRecord.time1 # print("4444444",metting_list) # room_obj = models.MeetingRoom.objects.all() # # return render(request,"index.html",{"metting_list":metting_list,"room_obj":room_obj}) class LoginForm(Form): username = fields.CharField( max_length=8, required=True, error_messages={ "max_length":"用户名长度不能大于8位", "required":"用户名不能为空", }, # label="用户名", # label_suffix=":", widget=widgets.TextInput(attrs={"class":"form-control","placeholder":"username","id":"username"}) ) password = fields.CharField( max_length=8, min_length=3, required=True, error_messages={ "max_length":"密码长度不能大于8位", "min_length":"密码长度不能小于3位", "required":"密码不能为空", }, # label="密码", # label_suffix=":", widget=widgets.PasswordInput(attrs={"class":"form-control","placeholder":"password","id":"password"})) def login(request): if request.method =="GET": form = LoginForm() return render(request,"login.html",{"form":form}) else: form = LoginForm(data=request.POST) if form.is_valid(): user = models.UserInfo.objects.filter(**form.cleaned_data).first() if user: request.session["userinfo"]={"id":user.id,"name":user.username} return redirect("/index/") # cookie的方式设置 # obj.set_cookie("name","zzz") # obj.set_signed_cookie("id",user.id,salt="aaaa") # obj.set_signed_cookie("id1",user.id) # return obj else: form.add_error('password','密码错误') return render(request,"login.html",{"form":form}) return render(request, "login.html", {"form": form}) def index(request): metting_list = models.ReserveRecord.time1 return render(request,"index.html",{"metting_list":metting_list}) def recording(request): response = {"status": True, "msg": None, "data": None} if request.method == "GET": current_data = datetime.datetime.now().date() #日期类型 #=======================获取指定日期所有的预定信息========================= try: ajax_date= request.GET.get("date") #字符串类型 # print(ajax_date,"============") ajax_date = datetime.datetime.strptime(ajax_date, '%Y-%m-%d').date() # print("date....",ajax_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)] # 吧这样的数据处理成字典的形式,提升查询速度 # { # 1:{ #room_id # 2:{"username":2,"user_id":3} #2表示time_id # } # } 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}} recrding_dict[i.room_id][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: print(room) tr = [] tr.append({"text": room.name, "attrs": {}}) for tm in models.ReserveRecord.time1: td = {"text": "", "attrs": {"room_id": room.id, "time_id": tm[0]}} if room.id in recrding_dict and tm[0] in recrding_dict[room.id]: #已预订,不确定是谁预定的,还得判断一下 td['attrs']['class'] = "chosen" if recrding_dict[room.id][tm[0]]['user_id'] == request.session["userinfo"]["id"]: #如果是自己预定 td['text'] = '我' else: #如果是别人预定,加一个disabled属性不可编辑,只有自己的能编辑 td['text'] = recrding_dict[room.id][tm[0]]['username'] td['attrs']['disable'] = True tr.append(td) data.append(tr) print('-==========',data) response["data"] = data except Exception as e: response["status"] = True response["msg"] = str(e) else: try: current_date = datetime.datetime.now().date() ajax_date = request.POST.get("date") ajax_date = datetime.datetime.strptime(ajax_date, '%Y-%m-%d').date() if ajax_date < current_date: raise Exception("查询时间不是当前的时间") post_data = json.loads(request.POST.get("data")) #由于发过来的数据是字符串,所以要转一下才能是字典 print(post_data) #{'ADD': {'1': ['5', '4'], '2': ['4', '7']}, 'DEL': {'2': ['4']}}} date = request.POST.get("date") #获取日期 # print(date) #2017-12-12 # 拿到数据以后 # 如果time_id在ADD里面有,在Del里面也有值,就删除了,因为数据库里面已经有值了。就直接把add里的和del里的删除就行了 for room_id ,time_list in post_data["DEL"].items(): if room_id not in post_data["ADD"]: continue else: 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) # print(post_data) #新增数据 reserverecord_obj_list = [] for room_id ,time_list in post_data["ADD"].items(): for time_id in time_list: # models.ReserveRecord.objects.create(room_id=room_id,time_id=time_id,date=date,user=request.session["userinfo"]["id"]) obj = models.ReserveRecord(room_id=room_id,timeline=time_id,data=date,user_id=request.session["userinfo"]["id"]) reserverecord_obj_list.append(obj) models.ReserveRecord.objects.bulk_create(reserverecord_obj_list) #删除会议室预定信息 from django.db.models import Q remove_reserverecord = Q() for room_id,time_list in post_data["DEL"].items(): for time_id in time_list: temp = Q() temp.connector = "AND" temp.children.append(("user_id",request.session["userinfo"]["id"])) temp.children.append(("data",date)) temp.children.append(("room_id",room_id)) temp.children.append(("timeline",time_id)) remove_reserverecord.add(temp,"OR") if remove_reserverecord: print(models.ReserveRecord.objects.filter(remove_reserverecord)) models.ReserveRecord.objects.filter(remove_reserverecord).delete() # print(remove_reserverecord,"remove_reserverecord") except Exception as e: response["status"] = False response["msg"] = str(e) return JsonResponse(response)
###############################################
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width"> <link rel="stylesheet" href="/static/bootstrap-3.3.7-dist/css/bootstrap.min.css"> <script src="/static/jquery-3.2.1.min.js"></script> <script src="/static/bootstrap-3.3.7-dist/js/bootstrap.min.js"></script> <title>Title</title> <style> .container { margin-top: 100px; } </style> </head> <body> <form action="/login/" method="post" novalidate> {% csrf_token %} <div class="container"> <h3 style="text-align: center">请先登录</h3> <div class="row"> <div class="col-md-4 col-md-offset-4"> <div class="form-group"> <label for="username">用户名</label> {{ form.username }} <p style="color: red">{{ form.errors.username.0 }}</p> </div> <div class="form-group"> <label for="password">密码</label> {{ form.password }} <p style="color: red">{{ form.errors.password.0 }}</p> </div> <input type="submit" value="登录" class="btn btn-success col-sm-7 col-md-offset-2"> </div> </div> </div> </form> </body> </html> login.html
###############################################
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width"> <title>Title</title> <link rel="stylesheet" href="/static/bootstrap-3.3.7-dist/css/bootstrap.min.css"> <link rel="stylesheet" href="/static/css/index.css"> <link rel="stylesheet" href="/static/bootstrap-datetimepicker-master/css/bootstrap-datetimepicker.css"> <script src="/static/jquery-3.2.1.min.js"></script> <script src="/static/bootstrap-datetimepicker-master/js/bootstrap-datetimepicker.js"></script> <script src="/static/bootstrap-datetimepicker-master/js/locales/bootstrap-datetimepicker.fr.js"></script> <script src="/static/bootstrap-datetimepicker-master/js/locales/bootstrap-datetimepicker.zh-CN.js"></script> </head> <body> <div class="container"> <div class="row"> <div class="col-md-11"> <h1>会议室预定</h1> <div class="data pull-right"> <button class="btn btn-primary" id="save">保存</button> </div> {# 日期#} <div class='col-sm-4 pull-right'> <div class="form-group"> <div class='input-group date' id='datetimepicker2' placeholder="请选择日期"> <input type='text' class="form-control"/> <span class="input-group-addon"> <span class="glyphicon glyphicon-calendar"></span> </span> </div> </div> </div> {# 表格#} <div> <table class="table table-bordered"> <thead> <th>会议室</th> {% for metting in metting_list %} <th>{{ metting.1 }}</th> {% endfor %} </thead> <tbody id = "tBody"> {# 方式一:也可以这样渲染#} {# {% for room in room_obj %}#} {# <tr>#} {# <td>{{ room.name }}</td>#} {# {% for metting in metting_list %}#} {# <td></td>#} {# {% endfor %}#} {# </tr>#} {# {% endfor %}#} {# 方式二#} {# 发送ajax请求渲染#} </tbody> </table> </div> {# 加载框#} <div class="shade hide"></div> <div class="loading hide"></div> </div> </div> </div> <script> //对Date的扩展 // 对Date的扩展,将 Date 转化为指定格式的String // 月(M)、日(d)、小时(h)、分(m)、秒(s)、季度(q) 可以用 1-2 个占位符, // 年(y)可以用 1-4 个占位符,毫秒(S)只能用 1 个占位符(是 1-3 位的数字) // 例子: // (new Date()).Format("yyyy-MM-dd hh:mm:ss.S") ==> 2006-07-02 08:09:04.423 // (new Date()).Format("yyyy-M-d h:m:s.S") ==> 2006-7-2 8:9:4.18 Date.prototype.Format = 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; }; $(function(){ //一开始加载的时候执行这个函数 initDatepickle(); initRecoringInfo(new Date().Format("yyyy-MM-dd")); initTdEvent(); initSaveEvent(); }); POST_DATA = { "ADD":{}, "DEL":{} }; //时间控件初始化 function initDatepickle() { $('#datetimepicker2').datetimepicker({ minView: "month",//设置只显示到月份 format: 'yyyy-mm-dd',//显示格式 {# autoclose: true,//选完自动关闭#} todayBtn: true, language:"zh-CN", startDate: new Date(), //以前的日期不能点 bootcssVer:3 //小箭头 }).on('changeDate', changeDate); } //点击日期插件的时候改变的函数 function changeDate(ev) { {# console.log(ev.date); //Wed Dec 13 2017 20:43:08 GMT+0800 (中国标准时间)#} CHOISE_DATE = ev.date.Format("yyyy-MM-dd"); //拿到的是插件的日期 initRecoringInfo(CHOISE_DATE); } CHOISE_DATE = new Date().Format("yyyy-MM-dd"); //当change的时候会修改日期,它拿到的是当前的日期 //获取预定记录发送ajax请求 function initRecoringInfo(date) { //这里穿进来的date就是上面转换成字符串的时间 {# 刚开始发送ajax的时候加载#} $(".shade,.loading").removeClass("hide"); $(function () { $.ajax({ url: "/recording/", type: "get", data: {"date": date}, success: function (data) { $(".shade,.loading").addClass("hide"); if (data.status) { $("#tBody").empty(); $.each(data.data, function (i, item) { {# console.log(i,item);#} var $tr = $("<tr>"); $.each(item, function (j, k) { {# console.log(j,k);#} var $td = $("<td>"); $td.text(k.text); $.each(k.attrs, function (m, n) { console.log(m, n); $td.attr(m, n) }); $tr.append($td); {# if (k.chosen){#} {# $("class").addClass("chosen")#} {# }#} }); $("#tBody").append($tr); }); //吧del,add里面有的内容清空 CHOSEN_DATE = new Date().Format('yyyy-MM-dd'); POST_DATA = { DEL:{}, ADD:{} }; } else { alert(data.msg) } }, error:function () { $(".shade,.loading").removeClass("hide"); alert("异常错误") } }) }) } //给td绑定事件,处理数据 function initTdEvent(){ //事件委派 $("tBody").on("click","td[time_id][disable!='true']",function () { //添加一个样式 var room_id = $(this).attr("room_id"); var time_id = $(this).attr("time_id"); if ($(this).hasClass("chosen")){ $(this).removeClass("chosen"); $(this).text(""); //退订room_id = 1 ,time_id = 5的 if (POST_DATA.DEL[room_id]) { //如果有room_id,就添加一个time_id POST_DATA.DEL[room_id].push(time_id) }else { POST_DATA.DEL[room_id] = [time_id] } } else if ($(this).hasClass("temp")){ //取消预定 $(this).removeClass("temp"); //从add中吧数据删除(先找到索引,然后如果存在就删除) var index = POST_DATA.ADD[room_id].indexOf(time_id); if (index!==-1) { POST_DATA.ADD[room_id].splice(index,1) //索引为n的删除一个 } }else { //要预定,吧预定的结果添加进去 $(this).addClass("temp"); if (POST_DATA.ADD[room_id]) { //如果有room_id,就添加一个time_id POST_DATA.ADD[room_id].push(time_id) }else { POST_DATA.ADD[room_id] = [time_id] } } }) } //通过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) } } }) }) } </script> </body> </html> index.html
###############################################
table{ margin-top: 80px; } td{ height: 80px; } .chosen{ background-color: gold; } .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); } .temp{ background-color: salmon; } index.css
###############################################