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="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> <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
mrbs - 初识的更多相关文章
- Django - 学习目录
Django 基础 web应用/http协议/web框架 Django简介 Django - 路由层(URLconf) Django - 视图层 Django - 模板层 Django - 模型层 - ...
- Android动画效果之初识Property Animation(属性动画)
前言: 前面两篇介绍了Android的Tween Animation(补间动画) Android动画效果之Tween Animation(补间动画).Frame Animation(逐帧动画)Andr ...
- 初识Hadoop
第一部分: 初识Hadoop 一. 谁说大象不能跳舞 业务数据越来越多,用关系型数据库来存储和处理数据越来越感觉吃力,一个查询或者一个导出,要执行很长 ...
- python学习笔记(基础四:模块初识、pyc和PyCodeObject是什么)
一.模块初识(一) 模块,也叫库.库有标准库第三方库. 注意事项:文件名不能和导入的模块名相同 1. sys模块 import sys print(sys.path) #打印环境变量 print(sy ...
- 初识IOS,Label控件的应用。
初识IOS,Label控件的应用. // // ViewController.m // Gua.test // // Created by 郭美男 on 16/5/31. // Copyright © ...
- UI篇(初识君面)
我们的APP要想吸引用户,就要把UI(脸蛋)搞漂亮一点.毕竟好的外貌是增进人际关系的第一步,我们程序员看到一个APP时,第一眼就是看这个软件的功能,不去关心界面是否漂亮,看到好的程序会说"我 ...
- Python导出Excel为Lua/Json/Xml实例教程(一):初识Python
Python导出Excel为Lua/Json/Xml实例教程(一):初识Python 相关链接: Python导出Excel为Lua/Json/Xml实例教程(一):初识Python Python导出 ...
- 初识SpringMvc
初识SpringMvc springMvc简介:SpringMVC也叫Spring Web mvc,属于表现层的框架.Spring MVC是Spring框架的一部分,是在Spring3.0后发布的 s ...
- 初识redis数据类型
初识redis数据类型 1.String(字符串) string是redis最基本的类型,一个key对应一个value. string类型是二进制安全的.意思是redis的string可以包含任何数据 ...
随机推荐
- centos7命令总结
1,查看cpu信息 lscpu 2,网络配置 ip route 查看路由 nmcli nmcli connection show 显示所有连接 nmcli connection show ...
- c++ 静态成员变量
在C++中,静态成员是属于整个类的而不是某个对象,静态成员变量只存储一份供所有对象共用.所以在所有对象中都可以共享它.使用静态成员变量实现多个对象之间的数据共享不会破坏隐藏的原则,保证了安全性还可以节 ...
- 模拟Excel中SUBSTITUTE函数
Excel中的SUBSTITUTE是一个很有用的字符串替换函数,其说明如下: 说明 在文本字符串中用 new_text 替换 old_text. 如果需要在某一文本字符串中替换指定的文本,请使用函数 ...
- Oracle之唯一性约束(UNIQUE Constraint)使用方法具体解释
Oracle | PL/SQL唯一索引(Unique Constraint)使用方法 1 目标 用演示样例演示怎样创建.删除.禁用和使用唯一性约束. 2 什么是唯一性约束? 唯一性约束指表中一个字段或 ...
- linux中,如何设置每隔2个小时就执行一次某个脚本?
需求描述: 今天同事问了一个linux上crontab定时任务的问题,说,如何调整一个定时任务每2个小时 执行一次,在此记录下. 操作过程: 1.通过以下的方式设置,每2个小时执行一次脚本 */ * ...
- 非常不错的前端框架Kendo-ui
近期公司在做重构,准备换前端框架由Extjs换kendo-ui,问什么要换框架呢?主要有以下几个原因: Extjs太重,偏向后端语言,前端写起来费劲 Extjs执行太慢(这是主要原因),因为Extjs ...
- Zookeeper(三)-- JAVA原生API
一.前提 jar包:zookeeper-3.4.9.jar,slf4j-api-1.6.1.jar,slf4j-log4j12-1.6.1.jar,log4j-1.2.15.jar 二.Demo pa ...
- STM32学习之路之MDK安装篇
- 《C++ Primer Plus》15.1 友元 学习笔记
15.1.1 友元类假定需要编写一个模拟电视机和遥控器的简单程序.决定定义一个Tv类和一个Remote类,来分别表示电视机和遥控器.遥控器和电视机之间既不是is-a关系也不是has-a关系.事实上,遥 ...
- poj_1151 线段树
题目大意 在平面上给定n个矩形,可以相互覆盖全部或者部分,求出矩形占据的总面积. 题目分析 将矩形按照x方向的进行分割之后,将平面沿着y方向划分一系列单元(不定高度),每个矩形在y方向上占据若干连续的 ...