10.14 预订会议室的小Demo
2018-10-14 17:12:32
越努力,越幸运.永远不要高估自己!
网上修改一下博客网站样式,做个仿qq空间的!
放上github连接 :https://github.com/TrueNewBee/pythonDemo/blob/master/%E9%A2%84%E5%AE%9A%E4%BC%9A%E8%AE%AE%E5%AE%A4.rar
整体实现不难:
预定会议室功能实现:
1.登入后 /login/ 后 可以看到所有人的预订
2.绿色为当前登录人的预订
3.点击某单元删除和添加预订,如果选择了重复则有提示
4.通过了Ajax请求,去掉了crsf跨站请求伪造
放上源码:
views.py
from django.shortcuts import render, redirect, HttpResponse
from django.contrib import auth
from .models import *
from django.db.models import Q
import json
import datetime
# 超级用户 root root1234
# zhen zhen1234 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") def index(request):
# 获取当前日期
date = datetime.datetime.now().date()
# 查看特定日期下的book
book_date = request.GET.get("book_date",date)
time_choices = Book.time_choices
room_list = Room.objects.all()
# 找到该日期下的预订的会议室
book_list = Book.objects.filter(date=book_date)
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:
# 根据flog的变化 加上特定的class 在前端通过class来添加css
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 room_id={} time_id={} class='item'></td>".format(room.pk,time_choice[0])
htmls += "</tr>"
return render(request, "index.html", locals()) def book(request):
print(request.POST)
post_data = json.loads(request.POST.get("post_data")) # {"ADD":{"1":["5"],"2":["5","6"]},"DEL":{"3":["9","10"]}}
choose_date = request.POST.get("choose_date") res = {"state": True, "msg" : None}
try:
# 添加预定
# post_data["ADD"] : {"1":["5"],"2":["5","6"]}
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")
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))
index.html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>Title</title>
<meta name="viewport" content="width=device-width, initial-scale=1"> <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>
.active{
background-color: green!important;
color: white;
}
.another_active{
background-color: #2b669a;
color: white;
} .td_active{
background-color: lightblue;
color: white;
}
</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> <table class="table table-bordered table-striped"> <thead>
<tr>
<th>会议室/时间</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 >
// js 必会的 字符串 数组 object { }
// 日期格式化方法
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]) : (("" + o[k]).substr(("" + o[k]).length)));
return fmt;
}; 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() }
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",
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>
models.py
from django.db import models
from django.contrib.auth.models import AbstractUser # 需要在settings配置 AUTH_USER_MODEL = "app01.UserInfo"
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)
urls.py
"""MRBS 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'^login/', views.login),
url(r'^index/', views.index),
url(r'^book/', views.book),
]
贴上笔记:
POST: 浏览器-------------------->server
"请求首行\r\nContent-Type:url_encode\r\n\r\na=1&b=2"
"请求首行\r\nContent-Type:application/json\r\n\r\n'{"a":1,"b":2}'" 在django的wsgi的request中:
request.body:元数据'{"a":1,"b":2}' if 请求头中的Content-Type==url_encode:
request.POST=解码a=1&b=2 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))
10.14 预订会议室的小Demo的更多相关文章
- Android -- 自定义View小Demo,动态画圆(一)
1,转载:(http://blog.csdn.NET/lmj623565791/article/details/24500107),现在如下图的效果: 由上面的效果图可以看到其实是一个在一个圆上换不同 ...
- 模仿京东顶部搜索条效果制作的一个小demo
最近模仿京东顶部搜索条效果制作的一个小demo,特贴到这里,今后如果有用到可以参考一下,代码如下 #define kScreenWidth [UIScreen mainScreen].bounds.s ...
- js特效 15个小demo
js特效和15个小demo 代码如下:images文件夹未上传 1.图片切换: <!DOCTYPE html> <html> <head> <title> ...
- dubbo泛化调用 小demo
前两天刚好有个同事来问是否用过 dubbo泛化 调用,不需要通过指定配置.第一次听到的时候,还是有点懵,但觉得有意思,可以学点东西. 立马百度了,找了demo,这篇比较容易上手(http://www. ...
- Android学习小Demo一个显示行线的自定义EditText
今天在处理一个EditText的时候,想着把EditText做成像一本作业本上的纸一样,每一行都可以由线条隔开,具体效果如下: 1)最开始的思路 一开始的想法是很简单的,找出每一行的高度,然后一行一行 ...
- React问答小demo
在学习react初期,看了一些视频和资料,react基础知识差不多学完,跟着网上的一个教程,做了一个小型的问答demo. 需求看图说: 1.点击"添加"按钮,显示问题输入表单,再次 ...
- 一周一个小demo — 前端后台的交互实例
这一周呢,本K在大神的指导下,完成了一个利用ajax与php文件上传处理相结合的一个留言板功能的小实例,下面就让本K来带大家瞅瞅如何实现这一种功能. 一.界面概览 首先我们来看一下这个小demo的具体 ...
- 基于BaseAdapter的Listview小Demo
ListView是android开发中比较常用的控件, 其中适配器模式可以选择: ArrayAdapter:简单易用,通常用于将数组或者List集合的读个包值封装成多个列表项 SimpleAdapte ...
- python turtle库的几个小demo
一.先上图 一个同切圆和五角星 上代码 import turtle #同切圆 turtle.pensize(2) turtle.circle(10) turtle.circle(40) turtle. ...
随机推荐
- ConcurrentLinkedQueue代码解析
原因:学习ConcurrentLinkedQueue是看到akka框架的默认邮箱是使用ConcurrentLinkedQueue实现的. 1. ConcurrentLinkedQueue在java.u ...
- mac上配置mysql与redis server,并结合Pydev准备某爬虫环境
mysql下安装mysql server mysql下安装redis server:https://www.jianshu.com/p/3bdfda703552 mac下安装配置redis:https ...
- sublime python3中读取和写入文件时如何解决编码问题
# -*- coding: utf-8 -*- #分析用户身份审核信息 #python 3.5 #xiaodeng #http://apistore.baidu.com/apiworks/servic ...
- 玩魔兽争霸无故退出 提示框显示"0x21101663"指令引用的"0x02704acc"内存该存不能为"read" 确定就会终止程序
20151002总结:下方法试过,没完全按照说的操作完,觉得有风险且那个read程序执行时间好长的,感觉有点干坏事的意思 ======================================= ...
- String拼接字符串效率低,你知道原因吗?
面试官Q1:请问为什么String用"+"拼接字符串效率低下,最好能从JVM角度谈谈吗? 对于这个问题,我们先来看看如下代码: public class StringTest { ...
- 电子证书 DER & PEM & CRT & CER
原文链接: http://blog.csdn.net/zqt520/article/details/26966603 证书与编码 本至上,X.509证书是一个数字文档,这个文档根据RFC 5280来编 ...
- Winform开发框架之通用Windows摄像头调用拍照--SNF快速开发平台3.3-Spring.Net.Framework
今天做了一个windows系统下调用摄像头.进行开启.关闭.拍照.设置等等功能演示. 进行源码贡献,欢迎大家下载使用 一.DEMO效果如下: 二.DEMO演示代码如下: using SNF.Utili ...
- CentOS 7 安装配置OpenVPN 2.3.12
1.下载安装包 #wget http://www.oberhumer.com/opensource/lzo/download/lzo-2.09.tar.gz#wget http://swupdate. ...
- 开源CFD并非万金油
今天有网友在群里讨论开发CFD软件的事情,众说纷纭,有网友提到"没有必要开发CFD软件了,直接使用开源OpenFOAM就行".但个人认为这说法还是有一些需要商榷的地方,开源软件也不 ...
- 解决Redis之MISCONF Redis is configured to save RDB snapshots, but is currently not able to persist o...
解决Redis之MISCONF Redis is configured to save RDB snapshots, but is currently not able to persist o... ...