表结构设计
from django.db import models # Create your models here. 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)
共三张表,用户表,会议室房间表和会议室预定情况表
URL设计
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'^login/', views.login), url(r'^book/', views.book), ]
index页面用来显示所以会议室的预定情况,login用来登录,book用来处理用户发送的数据和逻辑
index视图
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 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: 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 return render(request, 'index.html', locals())
首先我们要从访问的url中取出用户访问的日期,如果没有则默认为当天的日期,然后要取到所有的会议室信息和日期对应的会议室预定情况,如果将这些信息直接传到前端,渲染时由于一些逻辑无法使用,会造成一定的困难,所以我们直接在后端进行逻辑判断,将要渲染的标签内容生成字符串,然后再床给前端
<!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>会议室预订</h3> <div class="calender pull-right"> <div class='input-group' style="width: 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>
添加和删除JS效果以及ajax发送数据
<script> 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 () { $('#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) } else { CHOSEN_DATE = new Date().Format('yyyy-MM-dd'); } function book_query(ev) { CHOSEN_DATE = ev.date.Format('yyyy-MM-dd'); location.href="http://127.0.0.1:8000/index/?book_date="+CHOSEN_DATE } var POST_DATA = { DEL:{}, ADD:{}, }; 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")){ $(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({ 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>
点击某一个房间的时间段时我们应该让他变颜色,并且我们需要利用一种数据格式来存放我们要添加的内容,最后利用ajax直接发送到后端
Book函数
import json from django.http import JsonResponse def book(request): print(request.POST) response = {'status': True, 'msg': None, 'data': None} try: choice_date = request.POST.get('date') choice_date = datetime.datetime.strptime(choice_date, '%Y-%m-%d').date() post_data = json.loads(request.POST.get('data')) # 优化 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)
login函数
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) return redirect("/index/") return render(request, "login.html")
使用到的日期插件
http://www.bootcss.com/p/bootstrap-datetimepicker/